Pull to refresh
-3
0
​Василий Пупкинъ @tenshi

User

Send message
Примерно так:

var get = $jin.async2sync( $node.request.get )
var save = $jin.async2sync( $node.fs.writeFile )

var download = $jin.sync2async( function( from, to, def ){
var isDefault = false
try {
var content =get( from )
} catch( error ){
content = def
var isDefault = true
}
save( to, content )
return isDefault
})

download( 'http://ya.ru', 'ya.ru.html', '', function( error, isDefault ){
console.log( 'isDefault: ' + isDefault )
})

То есть благодаря node-fibers любую асинхронную функцию можно превратить в синхронную и наоборот с любой степенью вложенности. Более того, благодаря harmony proxy есть возможность автоматического параллелизма. Пример: github.com/nin-jin/node-jin#sod
А не проще ли просто унаследовать классы LocalPassport и FaceBookPassport от одного AbstractPassport? Зачем выделять часть функционала в отдельную сущность с которой потом приходится плясать как курица с яйцом?
Вот так вот не беспокоятся, а потом тратят на дебаг в 3 раза больше времени. Потому что беспокоиться о том что откуда пришло — необходимо. Потому, что нужно точно знать какие методы будут у объектов и как они будут действовать. Когда ты примешиваешь две пимеси, то у тебя возникает неопеделенность, которая сейчас работает как надо, а потом может сломаться. А находить такие баги довольно проблематично. Да и для разрешения конфликта используется как правило копипаста, либо хитрые конструкции типа Ext.Window.superclass.initConstructor.apply( this, arguments ) которые как ни странно ещё и работают через жопу.

И ничего во множественном наследовании плохого нет. Бывает плохая декомпозиция, да.
Хз, но если даже предположить, что мы передадим ей 50 джоулей и все они перейдёт в нагрев, то она разогреется лишь на пару градусов… сомневаюсь, что она сильно деформируется. Хотя, конечно, стоит это предусмотреть и сделать пулю со слегка зауженной попкой)
Из пальца высосал разницу)
Ну и что хорошего в этаком примешивании? Скорость? Одинаково. Потребление памяти? Одинаково. Простота реализации? А толку от простоты, если она приводит к трудноуловимым багам? По твоему ловить глюки, вызванные конфликтом методов, лучше, чем вменяемое сообщение о конфликте? Или писать костыли, когда нужно не просто переопределить метод, а дополнить?
А почему никто не пытается сделать тяжелый ферромагнитный боёк и легкую немагнитную пулю? Благодаря большим массогабаритам боёк легче будет разогнать в магнитном поле (читай — выше эффективность). А пулю расположить чуть дальше середины соленоида, где скорость бойка будет максимальной. По моим прикидкам если боёк будет в 3 раза тяжелее пули, тогда после удара он потеряет скорость в 2 раза и будет остановлен и потом затянут обратно соленоидом. А пуля наоборот приобретет скорость в полтора раза большую, чем максимальная скорость бойка, и, игнорируя магнитное поле соленоида, вылетит, используя вторую его половину как дуло. При этом нам не надо беспокоиться о точной синхронизации, остаточной индукции, и не удивлюсь, если тормозящий в поле боёк можно будет использовать для возвращения энергии обратно в конденсаторы.
И чем же множественное примешивание отличается от множественного наследования? х)

Я вот каких только вариантов повторного использования кода не перепробовал, но остановился на таком:
Есть типажи (штрихи/примеси/классы), они по умолчанию ничего не умеют.
Для типажей можно определять методы.
Типажи могут быть примешаны друг ко другу. При этом ранее определённые и позже определяемые в предках методы также копируются и в потомков каскадно.
В качестве типажей могут быть использованы любые глобально доступные объекты.
Каждый метод хранит информацию о том, какие методы он умеет перегружать.
Одноимённые методы определяемые в одном типаже проходят через процедуру «слияния».
Результатом «слияния» является либо один из методов (который должен уметь перегружать всех оставшихся), либо автоматически генерируемый метод-конфликт, хранящий в себе информацию о конфликтующих методах. Совсем как в системах контроля версий: типаж — это фичеветка.
Как раз недавно запилил либу для множественного наследования: javascript.ru/forum/project/40210-jin-i-snova-o-nasledovanii.html

Множественное наследование — это безусловно классно, но есть ряд проблем:
1. Конфликты имён. Не должны методы одной примеси молча затирать методы другой. В моей либе вместо затирания происходит создания метода-конфликта. Чтобы разрешить конфликт нужно примешать такой метод в описании которого указано, что он пригоден для разрешения конфликта между теми конфликтующими методами.
2. Не всегда понятно какой метод/свойство взяты из какой примеси/класса. В моей либе каждый метод имеет глобальный идентификатор. А также есть функция которая раздаст идентификаторы уже готовой структуре объектов.
3. Зачастую нужен доступ ко всем перегруженным методам, а не только к методу одного последнего предка. В моей либе все когда либо примешанные методы сохраняются в прототипе по тому самому глобальному идентификатору.

По ссылке больше примеров)
Хранить всё в репозитории это конечно хорошо. Потому что деплоить мы будем ровно то, что тестировали. И при этом не зависим от всяких сторонних тормозных сервисов типа npm.org. Более того, по аналогии с heroku в репозиторий стоит заливать и образ системы на которой всё это будет крутиться. Ой, как-то дофига весить оно будет ;-)

На самом деле всё проще: фиксируем версии или нет — не важно. деплоим на тестовый сервер, прогоняем тесты, если всё хорошо — клонируем тестовый сервер на боевой. не надо на каждом продакшен сервере запускать по деплою с его выкачиванием исходников, выкачиванием модулей, сборкой скриптов/стилей/спрайтов, компиляцией в байт-код… недавно ж даже битторрент выпустил приблуду для п2п синхронизации директорий.

а вот насчёт «офигенной фичи» иметь несколько модулей разных версий — тут я бы поспорил. Что есть в новой версии какого-то модуля пофиксили дыру в безопасности? Или существенно увеличили скорость? Да и вообще, иметь несколько версий одного модуля — лишнее потребление памяти. особенно, если модуль держит внутри себя кэш. Нафиг такое счастье. Как разработчик приложения я хочу чтобы все библиотеки были последней версии. И было бы классно, чтобы разработчики библиотек тоже шли в ногу со временем. А если не поспевают — им помогут те, кому больше всех надо. А поощрять использование устаревших версий — это плохо. В конце концом, если вылезла какая-то совсем большая несовместимость, которую самому не поправить — ну что ж, не будем обновлять этот злополучный модуль (а остальные будем) или найдём ему замену.
В любом деле надо минимизировать влияние человеческого фактора, а не искать виноватого.
Как с поддержкой https и websockets?

Странно, что никто не упомянул fiddler2.com/
Сплошная вкусовщина и противоречивые параграфы. То «использовать глаголы плохо», то «для действий используйте глаголы». Сразу бы написали, что «для сущностей используйте существительные, а для действий — глаголы», хотя это конечно очевидно.

Потом какой-то странный совет про CRUD over GET — это вообще за гранью добра и зла. Ладно бы ещё написали, что для получения данных использовать GET, а для изменения POST — этого достаточно для реализации чего угодно.

И вообще, CRUD — далеко не лучшее решение во многих случаях. Начиная с того, что Create и Update во многих случаях практически идентичные операции (разница лишь в том передаётся id записи или нет), заканчивая тем, что и действий с сущностями гораздо больше: Feed, чтобы покормить собаку, Walk, чтобы выглять и тд.

Коды ответов то рекомендуют использовать соответствующие HTTP коды, то говорят, что по умолчанию лучше выдавать всегда 200 o_0" И вообще много таких советов как усложнить себе жизнь: сделайте поддержку HTTP методов, а потом прикрутите их эмуляцию через ограниченный набор. Коли уж нужно втискиваться в рамки ограниченного набора — ну так и сделайте апи в этих рамках без всяких эмуляций. Незачем переусложнять.

Далее, префиксные параметры — позиционные с соответствующими косяками:
* Параметр всё-равно надо указывать даже если он не нужен. Например, мы хотим, чтобы язык выбирался автоматически — вместо /ru/ придётся писать что-нибудь типа /auto/. Либо допускать его не указание, но для этого нужны будут костыли типа «список возможных значений».
* Сложность добавления параметров. В серединку их добавить можно лишь со скрипом.
* Не всегда очевидно что означает тот или иной параметр. Имени-то у него нет. А если ещё и портянка из /auto/auto/ — вообще беда.

Опять же, псевдостатика хоть и популярна, но всё же менее понятна. Согласитесь, запись вида /ключ1/значение1/ключ2/значение2 (/owners/vasya123/dogs/bobby) — это какая-то хрень. Куда логичней иметь что-то типа /owner=vasya123/dog=bobby, а если чуть подправить пунктуацию, то получится всем известный формат ?owner=vasya123&dog=bobby

Но я бы предпочёл, что-то типа такого:

?dog;list для работы со списком собак
?dog=12345 для работы с отдельной собакой
?dog;list;owner=5678 для работы со списком собак отдельного человека
?dog;list;color=red;state=running;location=park для сложной фильтрации
?dog;list;api=13 просто указываем версию апи дополнительным параметром, если не указана — ну делаем редирект на «нормализованный урл» подставляя последнюю версию.
?owner;list;fields=name=address=dogs элегантный способ передать список значений, хотя и спорный, так как для поддержки такого формата сейчас нужно велосипедить.
?dog;list;offset=50;limit=50 пагинация
?convert;amount=100;from=EUR;to=USD конвертация 100 евро в доллары
?dog;list;format=json вместо формата по умолчанию используем json
?search=search+word глобальный поиск
?serch=search+word;type=owner=dog поиск по собакам и их хозяевам

Кстати, json далеко не лучший формат представления данных в апи. Потому что имеет косяки с расширяемостью. XML конечно тоже имеет проблемы, но сильно меньше. Зачастую изменение формата JSON приводит к необходимости увеличивать версию апи, потому что код работающий со старым форматом начинает падать на новом. В XML больше возможностей для расширения благодаря более абстрактным структурам (дерево из именованных узлов вместо массивов и хэшей в JSON). Есть ещё формат Tree, который ещё лучше чем XML в этом плане, правда библиотек под него почти что нет hyoo.ru/?article=%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D1%82+Tree;author=Nin+Jin

Для api можно вообще не заводить отдельный домент, например, на сайте hyoo.ru сервер всегда выдаёт довольно компактный api-xml, который в браузере преобразуется в страницу с помощью xslt.
не надо. очень «весело» внутри catch-блока не меть доступа к переменным объявленным в try. а после for-in не иметь возможности узнать, что тело ни разу выполнено не было. var + короткие функции = куда более практично.
на расстояние не более 2 метров. не велика заслуга.
число способов расположить N объектов последовательно

а вообще, когда мы говорим о физике с ее экспериментами, мы всегда имеем ввиду математические модели физических процессов. в реальности же нет никаких координат, скоростей, ускорений, сил, энергии и тп. «физический смысл» — это не более чем интуитивное описание этой модели. так, например, «ток» вообще нагло противоречит реальности, так как электроны бегут в противоположную сторону, что однако не мешает нам видеть в нём «физический смысл», потому что направление как правило не имеет особого значения.
mean time ops/sec
Q 98.002ms 10
When 16.895ms 59
Vow 12.302ms 81
fibers/promise 12.738ms 79

и это в свете того, что в последнем случае есть классная функция wait, приостанавливающая текущее волокно в ожидании ответа

benchmarks/comparison.js | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/benchmarks/comparison.js b/benchmarks/comparison.js
index 8520d17..7bcf306 100644
— a/benchmarks/comparison.js
+++ b/benchmarks/comparison.js
@@ -6,6 +6,34 @@ var cliff = require('cliff'),
Q = require('q'),
When = require('when'),
tests = {
+ 'fibers/promise': function(deferred){
+ var Fiber = require('fibers');
+ var Future= require('fibers/future')
+
+ var toResolve = [],
+ topPromises = [];
+
+ Object.keys(data).forEach(function(key) {
+ var promises= data[key].map(function(val) {
+ var promise = new Future();
+ toResolve.push({ promise: promise, val: val });
+ return promise;
+ })
+ topPromises.push(promises);
+ });
+
+ Fiber( function(){
+ var result= topPromises.map(function(promises){
+ return Future.wait( promises)
+ })
+ deferred.resolve()
+ }).run()
+
+ toResolve.forEach(function(obj) {
+ obj.promise.return(obj.val);
+ });
+ },
+
'Q': function(deferred) {
var toResolve = [],
topPromises = [];
я смотрю мы делаем что-то похожее)

распространять события на потомков — это слишком жёстко. а ограничения вида «распространяем событие на детей до второго колена» — слишком негибкие. я выбрал другой путь — родитель, если ему надо, отслеживает появление и исчезновение нужных ему детей и посылает события сразу тем, кому надо. при этом кастомные события имеют дефолтное поведение — сообщение об ошибке, что гарантирует, что никто не будет кричать в пустоту и кто-нибудь его обработает. ну и автоматический каскадный дестрой объектов позволяет решить проблему утечек. у меня еще было фолбэк для ие старых версий, но… ну его нахрен, выпилил эти костыли)
если интересно глянь модуль отслеживания виджетов github.com/nin-jin/jin/blob/master/component/jin_component.env%3Dweb.jam.js

почему ноды обрабатываются в обратном порядке?

пс, на самом деле w3-шный валидатор умеет подтягивать кастомные дтд, я когда то игрался, но хз где те исходники… и нафиг оно надо в dtd слишком не гибкие правила.

ппс, либо для кроссбраузерной работы с xml+xpath+xslt на клиенте: github.com/nin-jin/jin/blob/master/domx/jin_domx.env%3Dweb.jam.js
второй должен быть выше. потому что там мало голосов а значит низкая точность. но раз рейтинг у него больше — его с большей вероятностью посмотрят и проголосуют, тем самым увеличивая точность) когда его рейтинг перестанет лихорадить — выносить его из новинок в общий рейтинг.
ну а теперь разверни внутренности этого «root controller» и увидишь, что он состоит из субственно рутового контроллера, который вызывает другие контроллеры, а также из рутовой вьюхи, которая собирает разрозненные вьюхи в одну. то есть пресловутый mvc никуда не девается, просто вьюхи и контроллеры выстраиваются в иерархию.

другое дело, что mvc на клиент-серверную архитектуру вообще не проецируется. точно также как объекты херово ложатся в реляционную базу. ибо пользователь взаимодействует исключительно со вьюхой, а она уже толкает контроллеры, чтобы те обновили её саму. в вебе же всё взаимодействие клиента и сервера происходит через контроллер, который (в случае апи) может вообще никак не обрабатывать выходные данные и просто сериализовывать модель.

Information

Rating
Does not participate
Location
Ян де нова о-ва
Date of birth
Registered
Activity