• saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0

    Магия и стандарт не очень совместимы :)

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0
    будут ли в нем учтены файлы и вызовы функций по стеку, в которых нет макросов (они ведь макросы?) try-catch?

    Не будут, так как новая запись во внутренний стек saneex добавляется только при входе в блок try. Вероятно, можно придумать способ добавлять в него вызовы при входе в любую функцию, но точно не стандартными средствами.


    Оданко проблемы в этом нет, так как обычно при возникновении исключения вполне достаточно функций с try/catch внутри, а все промежуточные не интересуют.


    Пример:


      1 #include "saneex.h"
      2
      3 int subsub(void) {
      4   throw(msgex("Test"));
      5 }
      6
      7 int sub(void) {
      8   subsub();
      9 }
     10
     11 int main(void) {
     12   try {
     13     sub();
     14   } endtry
     15 }

    Вывод:


    Uncaught exception (code 1) - terminating. 
    Test
        ...at saneex-demo.c:4, code 0
    rethrown by ENDTRY
        ...at saneex-demo.c:14, code 1

    Как видите, в стеке только функции main (строка 14 с endtry) и subsub (4 с throw). Функции sub (строки 7-9) нет.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0
    Единственное что смутило: int i{ vec.at(4) }; — это C++ головного мозга?

    Это пример с Википедии в чистом виде. Не знаю, почему они написали именно так, а мне просто нужен был "независимый" пример использования исключений для бенчмарка и этот вполне подошел.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0

    Попробуйте скомпилировать #define с # внутри, без -E — у меня ругается:


    error: stray ‘#’ in program
    #define TRY #include ...
  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    +1

    Рассмотрим две проблемы из статьи:


    блок обязан заканчиваться на endtry

    Задача компилятора/среды программирования — максимально разгрузить программиста от контроля за мелочами (синтаксиса, платформы и прочего). В контексте моей библиотеки, может быть такой случай использования:


    try {
      func();
    } endtry   // <<<

    Допустим, код выше (где try и endtry это макросы) разворачивается в такой:


    if (xxx)    // "try"
    {
      func();
    }
    if (!handled) ...   // "endtry'

    Что будет, если программист забудет endtry?


    if (xxx)    // "try"
    {
      func();
    }

    Последней строчки нет. При этом в endtry происходит очистка стека и его пропуск является фатальной ошибкой, которую не поймать даже в рантайме (с точки зрения saneex блок try продолжает быть открытым до завершения процесса). А забыть endtry очень легко.


    Поэтому в saneex (см. исходники):


    #define try     {{{ if (_sxEnterTry2( setjmp(*_sxEnterTry()) ))
    #define endtry  _sxLeaveTry(__FILE__, __LINE__); }}}

    Обратите внимание на {{{ и }}}. Теперь, если пропустить endtry, код будет таким:


    {{{ if (xxx)    // "try"
    {
      func();
    }

    Это, очевидно, является синтаксической ошибкой, о чем компилятор сразу предупредит. Сравните с:


    {{{ if (xxx)    // "try"
    {
      func();
    }
    if (!handled) ... }}}  // "endtry"

    Забыть endtry и не заметить этого теперь можно только если пропустить 3 закрывающие скобки помимо собственно endtry, а это сложно сделать.


    нельзя делать return между try и endtry

    Теперь такой пример:


    try {
      return func();
    } endtry

    Это является точно такой же фатальной ошибкой, т.к. вызывает повреждение стека. Скобки нам уже не помогут, потому что endtry на месте. Можно было бы сделать что-то подобное:


    #define try    #define return abort();

    И тогда:


    try {
      abort(); func();
    } endtry

    В этом случае в рантайме при попытке выполнить такой блок гарантированно получили бы падение. Еще можно было бы #define return $#@!, чтобы вызвать синтаксическую ошибку — однако макросы не раскрываются рекурсивно, так что это не сработает и за пропущенным return, в отличии от endtry, приходится следить программисту.


    Вот это я и имел в виду.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0

    Имеется в виду, что при наличии volatile не требуется других модификаторов/факторов — факт наличия только volatile является достаточной гарантией, что переменная не попадет в регистр и к ней не будут применены другие описанные оптимизации.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0

    Имелось в виду использование стандартных переносимых конструкций, как, например, тройное { (как сделано для try и endtry) или #define return abort (но макросы не рекурсивны).

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    +1
    на фоне потока непрерывных новостей о коронавирусе она вселяет настоящий оптимизм.

    А я вот смотрю на счетчик просмотров и понимаю, что теперь Хабр уже точно "не торт" :/ Верю и надеюсь, что это временно.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0

    Насколько я понимаю, кэш в x86/x64 сделан так, чтобы программисту не нужно было о нем думать вообще — его как бы нет. За его корректность отвечает ЦП и переключение между ядрами для программы прозрачно. При использовании нескольких потоков это не отменяет необходимость синхронизации (atomic, критические секции и прочее), но сам кэш при этом всегда остается корректным (с точки зрения программы).


    Беглый поиск выдал вот такой вопрос-ответ на SO:


    x86 CPUs use a variation on the MESI protocol (MESIF for Intel, MOESI for AMD) to keep their caches coherent with each other (including the private L1 caches of different cores). A core that wants to write a cache line has to force other cores to invalidate their copy of it before it can change its own copy from Shared to Modified state.

    You don't need any fence instructions (like MFENCE) to produce data in one thread and consume it in another on x86, because x86 loads/stores have acquire/release semantics built-in. You do need MFENCE (full barrier) to get sequential consistency.

    То же самое относится к многопроцессорным системам.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0

    Мне тоже предпросмотра ссылок часто не хватает — было бы неплохо, если бы deniskin взял это на вооружение. Хотя, возможно, это лучше решать на уровне плагина в браузере, а не отдельно взятого сайта.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    0
    Про более медленную работу fprinf по сравнению с cerr << в общем-то понятно — printf это комбайн на все случаи жизни и под многие типы переменных, ему приходится разбирать строку форматирования. Вывод в cerr, полагаю, пользуется какими-то узкотипизированными форматёрами.

    Здесь интересно другое (см. таблицу, №3 и сноску): fprintf() в коде бенчмарка работает в 2-3 раза быстрее всегда, кроме одного случая в Visual Studio, когда в цикле выбрасывается исключение — тогда внезапно << начинает работать в 3 раза быстрее fprintf(). Причем это подтвердилось у другого читателя. Я не могу это никак объяснить. И это не повторяется на gcc.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    +4
    Я уже привык к тому, что если кто-то выкладывает контекстную ссылку — там нечто очень желательное к ознакомлению.

    Ну, 9600 бод и все-все-все вполне попадает в категорию "очень желательно" :)


    А если серьезно, то эта статья с претензией на "долгосрочный" справочный материал, поэтому ссылки на стандарт(ы), альтернативы и похожие работы обязаны присутствовать. Но вы ничего не упустите, если не будете по ним ходить, просто придется мне верить на слово.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    +1
    построение вот этого самого стека, насколько я помню — это как раз то, что в Java сильно снижает производительность при использовании исключений.

    Я с низким уровнем в JVM мало знаком, но, как пишут на SO, там используется подход zero-cost exceptions (см. в статье), то есть вся обработка делается в момент поимки исключения (если оно возникает). А Java — высокоуровневый язык с синхронизациями, объектами и прочим, поэтому такая обработка затратна.


    В saneex и "голом" С все наоборот — throw это почти что один longjmp(), который, фактически, только сбрасывает указатель стека (ESP). Затраты на этот сброс околонулевые, что показывают мои замеры, по которым throw/longjmp() в C быстрее, чем throw в C++ (где, как и в JVM, дело не ограничивается только изменением ESP).


    "Построение стека" происходит по мере вызовов try — там копируются параметры исключения (file, message и пр.) в статический массив, плюс вызывается setjmp(). Как раз последний является лимитирующим фактором, но от него избавиться нельзя никак, не уходя от C99. Но даже там счет идет на единицы-десятки мс при 100к повторений.

  • saneex.c: try/catch/finally на базе setjmp/longjmp (C99) быстрее стандартных исключений C++¹
    +1
    Я правильно понял, что само исключение у вас это структура, в которой есть сообщение, строка где его кинули, и указатель еще на что-то?

    Да: https://github.com/ProgerXP/SaneC/blob/master/saneex.h#L187


    struct SxTraceEntry {
      int   code;
      char  uncatchable;
      char  file[SX_MAX_TRACE_STRING];
      int   line;
      char  message[SX_MAX_TRACE_STRING];
      void  *extra;
    };

    можно ли будет посмотреть стектрейс, как скажем в Java, все строки, по которым проходил вызов до точки, где кинули исключение

    Конечно, в этом и смысл. На КДПВ справа внизу — именно такой stack trace.


    Uncaught exception (code 1) - terminating.
    Feeling blue today...
        ...at saneex-demo.c:7, code 0
    rethrown by ENDTRY
        ...at saneex-demo.c:11, code 1
    Bye-bye my little pony
        ...at saneex-demo.c:18, code 0
    rethrown by ENDTRY
        ...at saneex-demo.c:19, code 1

    Структура доступна в рантайме, ее можно проитерировать через sxWalkTrace():
    https://github.com/ProgerXP/SaneC/blob/master/saneex.c#L42


    Причем без усилий вообще.

    Да, "без усилий вообще" — это как раз "привычный по другим языкам механизм исключений" для меня. saneex это дает из коробки.

  • «Прокачиваем» notepad.exe
    0
    Есть ещё Notepad 2e с ещё большим количеством плюшек типа подсветки слов.
  • Ваш wi-fi расскажет мне, где вы живёте, где работаете и где путешествуете
    +2
    Ага. Сделали. Только они не совсем рандомные, не всегда включаются и вообще — почти не работают. Пруф.
  • Не учите фреймворки, учите архитектуру
    0
    А если честнее – потому что не видят альтернативы. А альтернатива есть, просто о ней забыли.

    Яростно плюсую, именно то, о чём я постоянно говорю коллегам. А альтернатива есть — "Backbone без фантиков", когда на единственном принципе строится вся библиотека. Как его повернёшь — то и получишь: наследование, привязки, наблюдателе, всё прочее… Просто, компактно.

    Полезная статья, буду отсылать на неё несогласных.
  • Дюжина дизайнерских косяков
    +1
    А как мелкое, но полезное (для кого-то) дополнение к более наглядным подсказкам — пусть будет!

    Согласен. Вопрос исчерпан, спасибо за обсуждение :)
  • Дюжина дизайнерских косяков
    +1
    Какой холиварный сабж оказался :)

    Согласен, что сейчас четкой грани нет, мой предыдущий коммент скорее пытался пояснить исторические корни этой разницы.

    Так ведь формы были ещё тогда, когда у элементов не было даже :hover. Точно во времена CSS1. ИМХО, тут создатели смотрели в первую очередь на десктопные интерфейсы, где, действительно, только особых случаях использовалась «рука» (как сейчас помню — в ссылках Acrobat Reader'а).

    Кстати, ссылки на другие языки в той выпадушке нормальные, их можно мидл-кликнуть в новую вкладку и т.д.

    Я тоже заметил, но тем сильнее мой аргумент про то, что раз никто (даже Яндекс с его экстазом по поводу интерфейсов) не делает 100% правильно и последовательно, то нет смысла к этому стремиться. Только путает.

    И у меня до сих пор осталось твердое убеждение, что нужны и ссылки на объекты («существительные»), и кнопки для действий («глаголы»), которые никогда не смогут заменить друг друга и визуально им тоже лучше быть разными.

    Это интересно, но всё равно не понимаю, почему их недостаточно просто сделать разными визуально, без изменения курсора при наведении по-разному. Опять же, на планшетах его нет — проблемы тоже нет (?), тогда зачем это городить для десктопов?

    Визуальные подсказки — как раз ответ, ИМХО. А курсор — уже так, дань традиции. Суровый верстальщик будет делать, как глаголет спецификация, выражая этим своё отношение к сабжу наподобие того, как некоторые технические переводчики пытаются найти английским словам русский эквивалент, а какие-то просто делают транслит (browser = браузер = обозреватель). Тоже холивар ещё тот.

    У меня опасение, что такая «забота о пользователе» через переупрощение

    Не буду спорить. Меня сейчас ни сколько не радует тотальная унификация (в этом контексте — обезличивание) интерфейсов с отпиливанием всего и вся, поэтому я б предпочёл описанное вами и стандартом поведение, и чтобы пользователи тоже его понимали, но сейчас идёт к тому, что пользователь перестанет понимать вообще что бы то ни было и разница между рукой и стрелкой для него будет просто верхом мыследеятельности.
  • Дюжина дизайнерских косяков
    +1
    а просто уводит пользователя со страницы, потенциально безвозвратно уничтожая любые изменения

    А форма нет? <button type=«submit»>? А <button type=«reset»>, которая не уводит, но уничтожает — это тогда как? Отдельный курсор надо?

    еще ссылку можно открыть мидл-кликом или комманд-кликом, перетянуть в другое окно, послать другу и т.д.

    Как аргумент — годится, но на практике не вытягивает. Возьмите тот же Яндекс: metrika.yandex.ru — они активно используют как обычные ссылки (которые <a href>), так и скриптовые ссылки (которые что-то там открывают в рамках этой же страницы). Первые выделяются сплошным подчёркиванием, вторые — точечные. Вроде всё сходится.

    А теперь попробуйте перетащить ссылку внизу, где указан язык (Ru). Что вам это дало? Зачем вам адрес с решёткой?

    На этом фоне имеем то, что кнопки, которые, как бы, меняют состояние страницы, уводят с неё и т.п. — не выделяются курсором, потому как это не в рамках спецификации, зато также имеем ссылки, которые нормальные, и ссылки, которые как раз не меняют состояния страницы (как тот язык) и при этом и те, и те выделяются одинаково или почти одинаково (Яндекс — редкое исключение), но зато у обоих точно всегда будет курсор-рука. При таком положении дел надо затратить пару секунд только на определение того, что собственно перед тобой («рука» есть? адрес кончается на "#"? адрес вообще показывается (может это span)?) и проще сделать это методом тыка.

    Как по мне так лучше всё делать универсально и не морочить никому голову тем, что вот это перетащить можно, а вон то — нет. Это всё равно никогда не соблюдается. (К слову, я был бы рад возможности нажать правой кнопкой на кнопку в GET-форме и получить ссылку, но увы и ах...)

    вопрос, кому придется потерпеть, остается открытым..:)

    По мне так однотипный курсор для всего нажимаемого — это в первую очередь интуитивно понятно в первую очередь самому пользователю. То, что там какие-то аспекты нажимаемости могут отличаться, и поэтому надо делать разные курсоры — это уже мысль пришла позже, да и то не ко всем (см. пример с Яндексом). У меня вот, как у опытного программёра (веб- и не только) никогда не возникало мысли, что «рука» обозначает возможность вызвать контекстное меню. Уверен, что у 95% обычных пользователей — и подавно.
  • Дюжина дизайнерских косяков
    0
    Уже и не чаял получить ответ.

    Очень интересно, спасибо. Это проливает свет на вопрос с указателем. «Affordance» звучит убедительнее других аргументов (например, что ссылка меняет состояние страницы — так ведь и кнопка тоже), но тем не менее всё равно субъективно — ИМХО, выделенная цветом и иногда подчёркиванием ссылка вполне себе отличима от текста. Но даже если и нет как курсор поможет её найти? Ведь для этого придётся наводить мышь на это место, но если ты его (место) и так нашёл — зачем ещё какие-то индикаторы?

    Тем более с новыми дизайнами вроде iOS 7+ и Metro кнопки нефигово потеряли в «affordance» и почти стали ссылками. Впору и трактовать всё кликабельное универсально.

    В общем, спасибо за ссылки.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    Видимо, мне не удалось полностью донести, в чем суть Sqimitive. Она не запрещает иметь много или мало методов. Это основа для твоего мини-фреймворка, который специфичен для данного приложения. Нужно несколько источников и кэширование? Напиши методы, используй ООП и все будет DRY и KISS.

    У тебя один опыт, у меня другой. Мнений столько же, сколько программистов. По моем опыту модели имеют один источник (иначе бы это были разные модели). У тебя не так? Сделай по-своему. Много кода это не займет, зато будет работать именно так, как ты хочешь.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    Не переживай, просто это не твой подход. Но именно ради этого был создан Sqimitive, когда тебя ничего не сковывает…
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    В примере я пытался показать, как технически происходит наследование (по крайней мере, как это выглядит снаружи). Я не хотел вдаваться в детали цепочек prototype, какая разница между prototype и __proto__, что такое hasOwnProperty() и прочего. Сказав «два независимых класса-прототипа» я, действительно, схитрил, но это не меняет того, что наследование с точки зрения привычного ООП в JavaScript нет. Это и было целью примера, и на мой взгляд она никуда не делась.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    Что за вид? Можно пример кода, пожалуйста?


    Хоть тот же to-do app или его кнопка «view source»:
    github.com/ProgerXP/Sqimitive/blob/master/demo/demo.js
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    А если для одной и той же модели данные приходят из разных мест в разных форматах, как это лавировать?

    Сейчас штатно в assignResp нельзя передать набор других правил (они берутся из _respToOpt), но я думаю добавить во второй аргумент (options) параметр, который будет использоваться вместо _respToOpt самой модели.

    В этом случае «assignResp_pusher» может быть алиасом для вызова assignResp(resp, {map: resp-to-opt}).
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    Zav, давай всё же будем объективны. Если у «полноценных» модели набор fetch/parse одни на один класс (как в Backbone), то чем они лучше Sqimitive/assignResp? В последнем случае ты можешь его настроить по-разному в рамках одной модели или коллекции — правила для трансформации, источник данных, что-то ещё.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    +1
    Только тут такой момент — любые данные укладываются в модель. Исключения очень редки.

    Это кому как. Мне лично кажется лишним создавать отдельную модель на каждый вид — особенно если там 1-2 флага, которые внутри этого вида только и используются.

    Ты же пишешь код не в самой библиотеке, а в подключаемом компоненте

    А, я понял, что ты изменяешь их собственный код. К компонентам у меня претензий нет. Но у меня был очень яркий опыт одного из первых проектов, где я использовал Backbone. Я расширял и расширял его (Backbone), пока в итоге проект не разросся до 3к строк + еще 4к строк «расширений». Это было неповоротливым и медленным. Конечно, ошибки проектирования/опыта имели значение, но всё равно не решающее. Это не единичный пример.

    На мой взгляд, надстройки над библиотекаим наподобие Marionette страдают как раз этим — пытаясь заткнуть дыри изначально отсутствующего функционала они производят на свет намного больше кода, чем это нужно.

    Пойми меня правильно — это всё лишь инструменты, и каждый выбирает инструмент, который ему удобен.

    Конечно, у каждого свой подход. И я отдаю себе отчёт, что мой — довольно редкий :)

    Что касается решений в других фреймворках — я их ищу и изучаю постоянно. Я не бегаю от новых идей.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    Ctrl+Enter + таймаут редактирования. Мда.

    На главной странице есть кнопка Costumize — бери что надо.

    Не буду спорить, так как CanJS не знаю.

    Не вижу причин атрибутов с датакастами, конвенторами данных и т.п. где-нибудь кроме моделей :-)

    Просмотри ещё раз про state-based programming. Опции — они полезны не только в моделях, более того, они наиболее полезны именно в представлениях. Смотри на мир шире. Не обязательно для каждого чиха создавать свой API.

    Ну так метод и реализуется в модели. Причем реализуется одной строкой, если не специфичный. В результате получаешь ощутимо меньше кода.

    А если у модели нет ID? Специфичный ID? Как ты реализуешь общую версию этого метода? Придётся его перекрывать в потомках? А как они отреагируют на составной ID (из нескольких полей)?

    Зачем вообще обобщённое понятие ID? Его можно избежать, добавив только там, где нужно. Кода на это потребуется минимумально.

    Накручивать абстракции вокруг базовых классов или бекэнд?

    Абстракции. Если в твоём проекте/тебе удобно использовать виды, модели и коллекции — наследуй от Sqimitive 3 класса, будут тебе обычные M-C-V. Так я делаю и не вижу в этом каких-либо проблем. Если же у тебя какой-то проект на 1000 строчек, который не будет развиваться — тебе, может, и одного хватит.

    Бэкенд это другая тема.

    Большинство библиотек позволяют их модифицировать не мешая основному коду программы, тем самым получаем свою сборку, которая легко обновляется до более новых версий.

    Хорошая библиотека не должна модифицироваться, это на мой взгляд грубое нарушение принципов модульности. Естественно, если делается свой форк — это одно, но отдельный форк на каждый проект? По-моему перебор. Иначе бы не было такого понятия, как плагины (которые я видел в том же CanJS).

    И про обновление ты явно хватил. Обновить Knockout с парой-тройкой плагинов? Ты знаешь его настолько хорошо, чтобы лазить в нутрях?

    Бонусом является то, что код отлично оттестирован, в отличии от самописного.

    Дело-то в том, что избыточный код не всегда даёт тебе всё, что нужно, и его тоже приходится доделывать. Либо искать, где там разработчики расставили свои капканы и почему твоя логика не согласуется с их. Я особенно сильно это прочувствовал, воюя с Backbone'овским sync.

    Мне нравится подход, когда ты точно знаешь как что работает, и что происходит.

    Это мне близко и я лишь говорил о том, что 1600 с комментариями и 11.5к — это всё же разные степени «когда ты точно знаешь как что работает». Я не уверен, что даже удалив все комментарии ты сможешь разобраться в таком объеме быстрее, чем в Sqimitive. Но, может быть, дополнительная функциональность для тебя более важна, и это нормально. Просто это не мой выбор, я вообще довольно аскетичен в выборе средств и инструментов.

    .е. на выходе имеет 1.5 тысячи строк для изучения. Уже не так страшно, да?

    Да, не так. Но, насколько я понял, CanJS это около 6к?
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    0
    На главной странице есть кнопка Costumize — бери что надо.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    –1
    Смотрели фреймворк canjs.com?

    Нет, первый раз слышу. Бегло просмотрел API и код — на первый взгляд кажется того же масштаба, что и Ember. Модули, много кода, разные компоненты. Особенно конструкции вроде таких меня сразу вгоняют в тоску:

    	/**
    	 * @add can.Component
    	 */
    	var Component = can.Component = can.Construct.extend(
    		
    		// ## Static
    		/**
    		 * @static
    		 */
    		
    		{
    


    Из 11 строк только одна несёт полезную нагрузку.

    Sqimitive — это полная противоположность. Здесь ничего нет, всё собирается вами, используя тонко подогнанный и маленький набор универсальных инструментов… А дальше — как глина. Хотите коллекции, модели и виды? Не вопрос, просто наследуйте их (кстати, оба проекта Belstone как раз и используют разделение на M-C-V, потому что это удобно).

    Просто я не вижу, зачем разделять их на уровне библиотеки, так как все свойства т.н. моделей (атрибуты), коллекций (фильтрация + вложенность) и представлений могут быть полезны для любого другого типа класса. Не хотите — не используйте вложенность в моделях, это ваше дело.

    Больше того, имена методов я специально выбирал не совсем стандартные (можно было назвать add, а не nest) — именно для того, чтобы их можно было перекрыть и назвать в соответствии со стилем в вашем проекте. Нужен getById? Сделайте его, используя доступные методы. Аналогично со всем прочим.

    Трюк в том, что при распределении работ в команде тебе достаточно знать интерфейс класса, и не задумываться как оно там внутри работает и выбирается.

    Всё верно, поэтому Sqimitive в серьёзном проекте напрямую не будет использоваться — между ним и приложением будет небольшая (или большая) прослойка-переход в виде тех же M-C-V. Её ведь всё равно приходится делать на том же Backbone. Потому что всегда свой подход хоть в чём-то, но не совпадает с подходом авторов библиотеки.

    Либо чуть более сложной конструкцией, с конкретизацией как тянем данные

    Важно соблюдать баланс между «преднаписанным» API и временем, которое требуется на его изучение. Можно подумать, что если в Ember почти 50к строк кода, то вам ни строчки не придётся писать самому. Ан-нет, костыли будут точно так же, как и при использовании другой библиотеки. Ещё и грузится дольше будет. (Ну, я утрирую, конечно.)

    Короче, из Sqimitive можно сделать основу для любого проекта, имея в её, гм, основе компактный код вместо многотысячных библиотек, которые так и так приходится доделывать. Кому-то такой подход нравится, кому-то нет.

    Вопрос такой: что если мы наследуемся от метода, в котором уже реализован +, и в нашем тоже есть +. Они оба выполнятся или будет перекрытие?

    Так вы наследуете не метод, вы перекрываете (с =) или расширяете (в других случаях) цепочку событий. Если у вас в базовом классе уже есть +event, а в потомке — ещё один +event, то в цепочке первым окажется метод (обработчик события) базового класса, после которого пойдёт метод потомка.

    Представьте, что когда вызывается extend() вы блок events берётся и передаётся в NewClass.on({events}). Это и есть наследование в стиле Sqimitive.

    Если есть желание, могу через скайп показать код пары проектов.

    Напишите в личку подробности.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    +4
    Пост написан от первого лица и у него нет пометки «Перевод» :)
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    +1
    Я действительно думал над этим, но в итоге решил оставить как есть, чтобы не было путаницы, какой класс наследовать. По задумке, когда вы используее Sqimitive, то наследуете в вашем приложении базовый класс, где собственно Sqimitive.Sqimitive используете единожды, а дальше вы упоминаете его только как App.MyBaseObject или App.Sqimitive (понятно, что ограничений тут никаких нет).
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    +1
    Не только Backbone. Мне не встречалась ни одна библиотека, где было бы вменяемо сделано наследование. Собственно, именно это и было основной причиной для создания своего велосипеда. Результат мне нравится.
  • Sqimitive.js — Frontend Primitive или «Backbone без фантиков»
    +1
    Рискую быть закиданным помидорами, но до отдельных тестов для Sqimitive я уже не добрался. Хватило и тех, которые писал для связанных проектов. Впрочем, это всегда можно поправить.

    Рад, что тексты понравились.
  • Wi-Fi сети: проникновение и защита. 3) WPA. OpenCL/CUDA. Статистика подбора
    0
    Да, об этом в самом конце второй части.
  • Wi-Fi сети: проникновение и защита. 2) Kali. Скрытие SSID. MAC-фильтрация. WPS
    +1
    Decloak точно для той же сети, MAC совпадает? Сети могут быть и безымянные, по идее, хотя мне не попадались и имя всегда раскрывалось. Можете попробовать ещё wifite — он похож на airdump-ng, запустить и наблюдать.
  • Wi-Fi сети: проникновение и защита. 2) Kali. Скрытие SSID. MAC-фильтрация. WPS
    +1
    См. третий абзац в «Скрытые сети… такие скрытые» — airdump-ng после успешного раскрытия заменит <length: 0> на имя сети, а в правом углу появится сообщение.
  • Wi-Fi сети: проникновение и защита. 2) Kali. Скрытие SSID. MAC-фильтрация. WPS
    +4
    Всегда с сочувствием относился к wi-fi хакерам с маками :)
  • Logitech выпустила клавиатуру для нескольких устройств
    0
    Теперь можно печатать на трех девайсах сразу. Тройной профит! Хотя конечно до BPS нам всем еще очень далеко