• Как отправить из textarea форматированный текст?

    Tyranron
    @Tyranron
    nl2br() для сохранения переносов.

    И htmlspecialchars(), чтобы корректно отображалось, если туда будете писать теги.
    Ответ написан
    1 комментарий
  • Как грамотно реализовывать каналы в Go?

    Tyranron
    @Tyranron
    Как вариант: вот.
    Постарался реализовать все условия задания. К сожалению, в задании ни слова о размере очереди. Я сделал её 2*N*P.
    Ответ написан
    Комментировать
  • Особая магия с channels в golang?

    Tyranron
    @Tyranron
    Сначала отвечу на второй вопрос.
    close() никакого отношения к scope не имеет вообще, он просто делает канал "закрытым", то есть таким, что при чтении значений из канала и записи из него возникает panic. Это всё. Соответственно...
    что случится, если закрыть буферизированый канал до того, как считать из него все значения, успевшие туда попасть?
    Канал закроется, при следующей попытке считать с него значение получите panic. Значения, что остались внутри, считайте потерянными, Вы их больше никак не получите.
    UPD: Это не так! (см. конец поста и комментарии)
    Соберется ли такой chan сборщиком мусора при уходе его в out of scope? Что будет с обьектами внутри канала?
    Соберется он сборщиком мусора только тогда, когда на него никто больше не будет ссылаться (если он объявлен локально, то да, out of scope). Объекты внутри тоже соберутся, если на них больше никто не ссылается. Те, на которые еще ссылается кто-то, останутся.

    Теперь замечания по Вашему примеру:
    select {
    case b <- number:
        fmt.Printf("Sent into b: %d\n", number)
    default:
        fmt.Printf("b chan closed\n")
    }
    Этот кусок здорово дезинформирует. Во-первых select на запись c default секцией никоим образом не спасает от panic при записи в закрытый канал. Он всего лишь делает запись в канал всегда неблокируемой. Как только Вы таким select'ом попытаетесь записать в закрытый канал что-то, словите сразу панику. Потому правильно для восприятия это место выглядит следующим образом:
    select {
    case b <- number:
        fmt.Printf("Sent into b: %d\n", number)
    default:
        fmt.Printf("Number %d just has been thrown away\n", number)
    }
    Если Вы сделаете канал a буферизированным, то тут Вам Ваши panic'и и полетят, потому что Вы пишете в закрытый канал.
    Закономерный вопрос: почему тогда panic'и не летят при небуферизированном канале а?
    Ответ: Вам просто везет =)
    Во-первых, на playground'е runtime.GOMAXPROC=1 и runtime.NumCPU=1. То есть в реальности все дело крутится в одном потоке и параллельность тут псевдо.
    Во-вторых, у меня локально (OS X) этот скрипт выкидывает panic'у после получения числа 25 даже при runtime.GOMAXPROC=1. Вам банально повезло, что внутренний планировщик горутин на playground'е ведет себя именно таки образом. При буферизированном канале он ведет себя немного иначе и Вы получаете закономерную panic'у сразу.

    Если совсем на пальцах по первому вопросу, то:
    При небуферизированном канале close(b) по каким-то соображения планировщика выполняется только после того как отработали обе горутины, если глянуть на вывод, то надпись "B:1" будет в самом конце. Потому то все и отрабатывает нормально, хотя это поведение совершенно не гарантированно логикой программы, наоборот, программа рассчитана на то, что close(b) выполнится сразу после того, как мы оттуда что-то считаем. Это и происходит, если канал a сделать буферизированым (надпись "B: 1" вылетает сразу), так как в этом случае планировщик меняет свои соображения, и мы получаем закономерную panic'у.

    Дополнительно:
    Канал b должен быть буферизированным, иначе, если горутина судья отработает быстрее чем главная горутина вообще начнет слушать канал, то все значения просто выкинутся. Эта проблема хорошо описана в этой статье на двух предпоследних абзацах.

    UPD:
    Я допустил ошибку, как верно указали в комментариях Виталий Яковенко и SilentFl, закрытый канал не выдает panic при чтении с него. Он разрешает считать все значения, которые в нем остались, после чего отдает "пустые" значения для свое типа, больше никогда не блокируя выполнение.
    Закрытый канал panic'ует только при попытке отправить в него значение.
    Ответ написан
  • Как в golang получить информацию о процессе?

    Tyranron
    @Tyranron
    Стандартной библиотекой Go не получится, потому что это дело совсем не платформо-независимое.
    Обычно предлагают или парсить вывод top/ps, или стучаться в /proc/stat .
    Детали с примерами на SO.

    UPD: Но если нужно мониторить потребление памяти программы написаннной на Go, а не вообще любого процесса, то для уменьшения накладных расходов и более точной информации, лучше организовать это дело внутренними средствами Go через доп. интерфейс или логирование.
    Пример: How to get statistics about memory in Golang
    Ответ написан
  • Как в Go получить абсолютный путь запущенной программы?

    Tyranron
    @Tyranron
    Все правильно, go run - это же не Ваш бинарник, это утилита, которая сначал компилит Ваш код в бинарник и помещает во временную директорию под уникальным номером, потом запускает. Gin, вероятно, действует иначе, компилит в ту же директорию где лежит скрипт и запускает.
    Чтобы не хардкодить - прекратите запускать сервера с помощью go run. Команда
    go build -o myapp && ./myapp
    не сильно сложнее, но зато будете уверены, что бинарник запускается там, где нужен.
    Обычно go run принято использовать для небольших скриптов, которые выполняют разовую работу, то есть таких, которые компилить нет особо смысла, хочется сразу прогнать.

    P.S. Пользуясь случаем, скромно попиарюсь и выложу ссылку на свою поделку для простой демонизации простых приложений на Go, когда юзать какой-то продвинутый гипервизор процессов влом или неоправданно. Но он пока только для linux/osx.
    Загляните в код, он небольшой и там это все есть.
    Ответ написан
  • Как правильно работать с веткой feature в git, чтобы регулярно забирать обновления из основной?

    Tyranron
    @Tyranron
    Если Вы регулярно мерджите актуальную develop в свою ветку, значит и конфликты решаете по мере их возникновения, соответственно при мердже Вашей ветки в develop больших проблем не должно быть, это даже будет банальный fast-forward, если под актуальностью понимать последний коммит в develop.
    Rebase зачем тут делать - не понятно, разве что "хочу историю чище", но в таком случае можно и через git merge --squash слить фичу в develop после ее реализации.

    Мой совет: обычный merge develop'а себе в ветку, чем чаще, тем лучше (легче будет конфликты решать).

    Собственно, Вы и сами это озвучили.
    Ответ написан
    Комментировать
  • Стоит ли использовать FrameWork'и для Go?

    Tyranron
    @Tyranron
    Ну, а Вы попробуйте, или просто на слово поверите? =)
    Придумайте типичное тестовое задание небольшое аля наваять/сделать форму регистрации/входа на сайт с механимом сессий (считай залогинен/незалогинен). Решите эту задачу сначала с помощью фреймворков, а потом только с помощью стандартной библиотеки (или наоборот, не суть).

    Вообще, все зависит от задачи, которую предстоит решить. По моему опыту (небольшие проекты) - на Go легко, удобно и приятно делать минифреймворки/тулкиты под конкретную задачу, если Вас не устраивают существующие решения. Но для чего-то большого, чувствую, что на определенном этапе голый net/http без какой-либо продуманной архитектуры приложения начнет приносить боль.
    Ответ написан
    5 комментариев
  • Как объединить массивы?

    Tyranron
    @Tyranron
    Пока писал, Вы двигались в том же направлении =) .
    Вот такой велосипед:
    function array_merge_sorted($first, $second)
    {
        $out = [];
        for (
            $f = 0, $s = 0,
            $firstLength = count($first),
            $secondLength = count($second);
            $f < $firstLength || $s < $secondLength;
        ) {
            if (!isset($first[$f])) {
                $out[] = $second[$s];
                ++$s;
            } elseif (!isset($second[$s])) {
                $out[] = $first[$f];
                ++$f;
            } elseif ($first[$f] > $second[$s]) {
                $out[] = $second[$s];
                ++$s;
            } else {
                $out[] = $first[$f];
                ++$f;
            }
        }
        return $out;
    }

    По времени: 1 проход по первому масиву + 1 проход по второму массиву.
    По памяти: 1 размер первого массива + 1 размер второго массива, лишних аллокаций нет.
    Ответ написан
    4 комментария
  • PDOStatement::bindParam - почему не получается биндить через foreach?

    Tyranron
    @Tyranron
    Потому, что нужно читать документацию:
    В отличие от PDOStatement::bindValue(), переменная привязывается по ссылке, и ее значение будет вычисляться во время вызова PDOStatement::execute().
    Ответ написан
    1 комментарий
  • Как решить проблему с json?

    Tyranron
    @Tyranron
    ArrayList тут, скорее всего, совершенно ни причем, дело в порядке сериализации полей классов.
    Вот что нашел здесь:

    Еще один момент, который многие не знают. При стандартной сериализации учитывается порядок объявления полей в классе. Во всяком случае, так было в ранних версиях, в JVM версии 1.6 реализации Oracle уже порядок неважен, важны тип и имя поля. Состав же методов с очень большой вероятностью повлияет на стандартный механизм, при том, что поля могут вообще остаться теми же.

    То есть, логично предположить, что при сериализации класса совершенно не гарантируется сохранение ни порядка объявления полей в классе, и уж точно, ни порядка передачи параметров в конструктор класса.

    P.S. А зачем Вам в JSON'е гарантированно сохранять порядок полей? Может это уж и не так кричтично на самом деле?
    Ответ написан
  • Как написать свой транслятор одного языка в другой?

    Tyranron
    @Tyranron
    Собственно, для Go парсер и прочие ништяки поставляются в его стандартное библиотеке:
    golang.org/pkg/go

    Но, не все так просто. Недостаточно просто взять и на основе одного синтаксиса сгенерировать другой. У языков может различаться достаточно серьезно модель работы с памятью. Например, учитывайте, что JS выполняется в одном потоке, а Go - не обязательно, это делает бессмысленными многие элементы в Go, которые направлены на синхронизацию. Также я, например, сходу не соображу как оптимально ретранслировать в JS такие низкоуровневые вещи как указатели, ведь сам по себе JS не дает "щупать" их ручками, как позволяет это Go. И таких моментов, если копнуть дальше, будет ещё много, потому что сладость Go - в его рантайме, который нельзя вот так просто взять и втащить на горбу JS в браузер.
    Можно, конечно, взять и тупо наложить синтаксис Go на однопоточную модель JS, его должно хватить, но это уже будет не чистый Go, а немного другая его спецификация под другую модель памяти, со своими подводными камнями. И тут встает вопрос: а достаточно ли выразителен Go для тех задач, которые решает JS в браузере? В погоне за внешним видом и синтаксисом не нацеп ли мы корпус от трактора на легковую машину, в результате своего то добившись, но поимев проблемы как минимум с парковкой? Все-таки языки создавались для решения разных задач.

    Что касается Python - тут дела должны быть лучше, так как модели языков ближе. Уверен, что какие-то ретрансляторы из Python в JS уже есть. Я много раз слышал о том, что как бы хорошо было в браузере на Python ваять, а мир энтузиастами полон =) .

    Возвращаясь к проблеме ретрансляции, @mututunus задал Вам правильный вектор. Изучите вопрос глубже, посмотрите успехи других на этом поприще. У того же Dart и JS - очень похожи модели языков, и это неспроста. При первом взгляде Dart кажется таким себе JS на стероидах с нормальной асинхронщиной, пакетами, опциональной статической типизацией и прочими сладостями. Не удивительно, что он легко и достаточно хорошо транслируется в JS. Более того, его создавали как раз как замену JS, то есть для решения задач в браузере, он под это заточен в некотором смысле, что, конечно же, выливается в определенном дизайне языка и определенных его концепциях.
    Ответ написан
    Комментировать
  • Какой аналог Python функции chr() в Golang?

    Tyranron
    @Tyranron
    Это должно помочь:
    stackoverflow.com/questions/20922598/golang-packin...
    Ответ написан
    Комментировать
  • На чем написать интерфейс к БД?

    Tyranron
    @Tyranron
    Варианты бывают самые разные, ограничение лишь в фантазии. Писать GUI можно на чем угодно.
    Я бы посоветовал Вам конкретнее сформулировать требования, и руководствуясь ими станет яснее на чем и как писать.
    Примерные вопросы по требованиям:
    - где хранить базу: локально на компе или все же на каком-то центральном сервере?
    - нужен ли одновременный доступ к ней для нескольких людей/устройств?
    - действительно нужна ли автономность и возможность работы без сети?
    ...и тому подобное.
    В результате, если Вам нужна база, которой будут пользоваться много людей и автономность не нужна, то лучше закинуть на сервер и сделать web-морду, если же нужна проста обертка вокруг базы локально на одном компьютере для одного человека и интернет до лампочки (аля тот самы файл экселя на стероидах), то можно вообще воспользоваться microsoft access'ом, или наваять GUI практически на любом языке с приятной (в использовании) графической либой - C#, Ruby, Python....тысячи их.
    Ответ написан
  • Как мне загрузить файлы проекта на PhpStorm 7 ?

    Tyranron
    @Tyranron
    Вы скорее всего просто не указали в настройках Project Settings -> Deployment на вкладке Mappings поле Deployment path on server. Если там ничего не указано, то шторм просто не знает откуда/куда грузить файлы, хоть на удаленный хост и пускает посмотреть что там есть (или копировать ручками). Если не требуется указывать там какой-то специфический путь, просто поставьте слэш ( / ).
    Ответ написан
    2 комментария
  • Golang gorm запрос логического значения у базы данных, не поле таблицы, это возможно?

    Tyranron
    @Tyranron
    На чистом database/sql:
    r, err := db.Query("SELECT 1 FROM items WHERE origin='http://example.com/path' LIMIT 1")
    if err != nil {
        // Oops!
    }
    thisTableReallyHasThatRow := r.Next()
    r.Close()


    То же самое можно провернуть и на gorm'е с помощью raw sql, или с помощью RecordNotFound() сделать примерно так:
    thisTableReallyHasThatRow := !db.Find(&Item{}, "origin = ?", "http://example.com/path").RecordNotFound()
    Ответ написан
    1 комментарий
  • Что быстрее: обработка данных на pgsql или php?

    Tyranron
    @Tyranron
    На pgsql будет быстрее, естественно, но для системы в целом - базу лучше не нагружать лишней работой, которую можно выполнить и так.
    Ответ написан
    Комментировать
  • На повестку дня: Ruby On Rails или Node.js или php или Python?

    Tyranron
    @Tyranron
    @Shetani безусловно прав. Я бы Вам не советовал полагаться на какой-то единственно верный язык, ведь они всего лишь инструменты. В одной конторе будут бэк писать на пайтоне, в другой на рельсах, в третьей бэк будет на php. Выбор может зависеть от многих факторов и, чаще всего, выбирать будете не Вы. Потому, по-хорошему, советую изучить все предложенные Вами варианты. И не надо бояться, что времени не хватит. Хватит. Много времени может занять изучение первого языка для бэка (так как надо будет въехать и прочувствовать как этот бэк работает) и второго (потому что нужно будет переосмыслить то, что Вы выучили в первом), а дальше пойдет по накатанной.
    Тоже советую начать с рельс и руби, ибо не зря в тренде.
    Потом советую подергать node.js, ибо однопоточность и асинхронность, а также, по желанию, фулл-стэк фреймворки (единый код на сервере и на клиенте - meteor и другие).
    Дальше уже php и python для полноты картины.
    Также советую добавить в список Go, Java/Scala и Erlang.
    Ну и совсем уже на любителя - Haskell + Yesod...практической ценности в этом будет мало, но для понимания (а также расширения сознания и просветления) очень даже полезно. =)
    Ответ написан
    Комментировать
  • Правильно составить .htaccess?

    Tyranron
    @Tyranron
    Исключить реально существующие папки и файлы можно добавив для правила 2 условия:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([_a-zA-Z0-9]+)$ /system/page/profile.php?username=$1 [L,QSA]
    Ответ написан
    Комментировать