1. JavaScript / Говнокод #19692

    +7

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    module.exports = leftpad;
    function leftpad (str, len, ch) {
      str = String(str);
      var i = -1;
      if (!ch && ch !== 0) ch = ' ';
      len = len - str.length;
      while (++i < len) {
        str = ch + str;
      }
      return str;
    }

    Мама, мама, я написал Модуль для NodeJS!!!

    Запостил: gost, 25 Марта 2016

    Комментарии (41) RSS

    • А добавлять пробелы по одному слева в цикле, это для JS программистов нормально?
      Ответить
      • У меня тоже бомбануло от кода, когда статью на кабре прочитал.
        Миллионы скачиваний, "абсракция", и ни один JS-адепт не обратил внимания на то, что алгоритм квадратичный.
        В теории, конечно, для больших строк паддинг врядли кто-то будет вызывать, не узкое место, но в модуле из ОДНОЙ ФУНКЦИИ, КАРЛ можно было и не за квадрат реализовать.
        Ответить
        • Ну строки же в ж.скрипте не такие, как в сишке. Конкатенация у них O(1), это потом, если например распечатать надо, то будет O(ln n).
          Ответить
          • Да, похоже, в FF используют Ropes. Не нашёл гарантий O(1)... Верёвки обычно балансировать надо, иначе доступ по индексу тормозной будет, поэтом в худшем случае должно быть O(log N) на конкатенацию.

            В V8 какая-то другая оптимизация для конкатенаций в цикле.

            Ок, теперь понятно, что рассуждать об алгоритмической сложности программ на JS можно только эмпирически.
            Ответить
            • Ну я бы балансировал тогда, когда это улучшает производительность. Но тут же возникает вопрос: а так ли нужна эта балансировка при том, что строки не изменяются и у нас есть информация о том, ссылается ли кто-то на под-дерево или нет. Может лучше просто склеить их при доступе по индексу?
              Ответить
              • > нужна эта балансировка при том, что строки не изменяются

                Балансировка нужна, чтобы быстро искать, неизменяемость тут не при чём.
                Если тупо приклеивать, получается колбаса вида
                .  join
                  /    \
                a       join
                       /    \
                      b     ...
                               \
                                join
                               /    \
                              z      s
                Доступ по индексу будет медленным.

                > Может лучше просто склеить их при доступе по индексу?
                Наверное, можно, но тогда в каждый доступ по индексу приезжают нетривиальные ветвления. В целом оптимизаторы могут и такое выпилить, но уж как-то всё сложно и непредсказуемо получается.
                Ответить
            • JS - не тот язык, где нужно рассуждать - так нужно лепить замок из говна, быыыыыстро, блеать!
              Ответить
              • У тебя не должно времени писать на гк, замок рушится, обмажь еще говном.
                Ответить
          • Всмысле они как в паскеле и в MFC чтоли? Сначала хранится длина строки, и можно за одно сложение узнать ее конец?
            Ответить
            • Нет, смысл в том, что строки не являются массивами, а деревьями, где значения в узлах - массивы. Вставка в такое дерево может быть сделана за О(1) потому что можно просто взять вершину этого дерева и заменить ее на вставляемый узел, а потом назначить бывшую вершину веткой вставляемому узлу.
              У разных деревьев могут быть разные контракты относительно того, как соотносятся значения в узлах. Конкретно в ropes нужно поддерживать контракт, что количество дочерних узлов в правой ветке примерно равно количеству узлов в левой ветке.
              Вставка может нарушить контракт, но вот вопрос когда нужно заниматься исправлением: можно это делать при каждой вставке, а можно это делать при доступе к элементам.
              Ответить
              • все
                уже читаю
                https://en.wikipedia.org/wiki/Rope_(data_structure)
                Ответить
        • Ну дык, "абсракция" же. Детали реализации, сложность, условия нормальной работы, гарантии знать не нужно. Работает, и ладно.
          Ответить
          • "Наш сайт точно откроется за время жизни Вселенной"
            Ответить
            • Какое-то ненадёжное обещание.

              Наш сайт точно откроется за время жизни Бога*
              * При условии существования Вселенной, планеты Земля, человечества на определённом этапе развития, ЭВМ определённой архитектуры, доступности энергии и ежедневных взносов пользователей в размере 0.05 МРОТ.
              Ответить
        • Там в реквестах уже есть реализация которая за логарифм пробелы собирает, ахаха.
          Ответить
    • https://www.npmjs.com/package/isarray
      https://www.npmjs.com/package/isnumber
      Цирк.
      Ответить
    • Навскидку от человека, посвятившего изучению JavaScript целых 2 дня:
      str = Array(len+1).join(ch) + str; //так лучше?
      И вообще, как это лучше всего делается?
      Ответить
      • Думаю, тут надо подождать, пока все обновятся до актуальных версий и использовать String.prototype.repeat:
        function leftpad (str, len, ch) {
          if (!ch && ch !== 0) ch = ' ';
          len = Math.max(0, len - str.length);
          return String(ch).repeat(len) + String(str);
        }

        Иначе это - какие-то догадки и споры о внутреннем мире неразделанного медведя.

        > str = Array(len+1).join(ch) + str; //так лучше?
        Зависит от версии интерпретатора. Может, в какой-то эту операцию сильно соптимизировали.
        Ответить
        • >Думаю, тут надо подождать, пока все обновятся до актуальных версий
          Двоичный поискДвоичное склеивание рулит.

          Polyfill

          This method has been added to the ECMAScript 6 specification and may not be available in all JavaScript implementations yet. However, you can polyfill String.prototype.repeat() with the following snippet:

          if (!String.prototype.repeat) {
            String.prototype.repeat = function(count) {
              'use strict';
              if (this == null) {
                throw new TypeError('can\'t convert ' + this + ' to object');
              }
              var str = '' + this;
              count = +count;
              if (count != count) {
                count = 0;
              }
              if (count < 0) {
                throw new RangeError('repeat count must be non-negative');
              }
              if (count == Infinity) {
                throw new RangeError('repeat count must be less than infinity');
              }
              count = Math.floor(count);
              if (str.length == 0 || count == 0) {
                return '';
              }
              // Ensuring count is a 31-bit integer allows us to heavily optimize the
              // main part. But anyway, most current (August 2014) browsers can't handle
              // strings 1 << 28 chars or longer, so:
              if (str.length * count >= 1 << 28) {
                throw new RangeError('repeat count must not overflow maximum string size');
              }
              var rpt = '';
              for (;;) {
                if ((count & 1) == 1) {
                  rpt += str;
                }
                count >>>= 1;
                if (count == 0) {
                  break;
                }
                str += str;
              }
              // Could we try:
              // return Array(count + 1).join(this);
              return rpt;
            }
          }
          Ответить
      • Array(len+1).join(ch) + str случаем не вернет строку длинной 2 * (len + 1) - 1 + str.Length?
        Ответить
        • Хромоинтерпретатор:

          s=Array(6).join('.')
          > "....."
          s.length
          > 5

          Вроде, всё в порядке
          Ответить
    • Господи, оказывается эта история породила нехилый шитщторм.

      We should do that for each language we like to troll.

      A Java left pad implementing a Padder class instanciated by a PadderFactory that you can get by a PadderInjector from a PadderRegistry all that accepting an AbstractPaddingString.

      Then one in Ruby where you monkey patch the string that it pads, then add an AUTO_PAD settings set to True by default and a fluent API to chain padding.

      Then one version PHP version containing pad_string, then real_pad_string that deals with unicode, then real_pad_string_i_swear_this_time that that call str() on parameters automatically.

      Then a Haskell one with a monad and a trampolin and some |=> giberrish to mix it all.

      Then a Go one that creates a string padding microservice based on goroutine. With a docker file, just in case.

      And because we should never forget to be able to mock ourself, an aio_string_pad which gives you an asyncronous padding coroutine, but under the wood calling run_in_executor, and optionally auto start an event loop.
      Ответить
      • Посоны еще зделали облачный left-pad

        http://left-pad.io/

        8         d'b   o                           8     o
        8         8     8                           8
        8 .oPYo. o8P   o8P       .oPYo. .oPYo. .oPYo8    o8 .oPYo.
        8 8oooo8  8     8  ooooo 8    8 .oooo8 8    8     8 8    8
        8 8.      8     8        8    8 8    8 8    8     8 8    8
        8 `Yooo'  8     8        8YooP' `YooP8 `YooP' 88  8 `YooP'
        ..:.....::..::::..:::::::8 ....::.....::.....:..::..:.....:
        :::::::::::::::::::::::::8 ::::::::::::::::::::::::::::::::
        :::::::::::::::::::::::::..::::::::::::::::::::::::::::::::
        
        Welcome to left-pad.io!
        Ответить
        • ## History
          
          On March 22nd 2016, a terrible tragedy befell the Node.JS community. A popular
          microframework for robust string expansion, `left-pad`, was removed from
          npmjs.com.
          
          This resulted in broken deploys worldwide, a sudden and complete inability to
          appropriately zero-pad the fractional real cent value of many stock options,
          and untold billions of dollars in economic damage to the still nascent startup
          ecosystem of String Manipulation as a Service.
          
          ## A microservice saviour appears
          
          In order to prevent such a terrible tragedy from occurring ever again during
          our lifetimes, `left-pad.io` has been created to provide all the functionality
          of `left-pad` AND the overhead of a TLS handshake and an HTTP request.
          
          Less code is better code, leave the heavy lifting to `left-pad.io`, The String
          Experts™.
          
          ## How do I make use of left-pad.io?
          
          Simple! Just make a request to `https://api.left-pad.io`:
          
          ```
          $ curl 'https://api.left-pad.io/?str=paddin%27%20oswalt&len=68&ch=@'
          {"str":"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@paddin' oswalt"}
          ```
          
          The query parameter names `str`, `len`, and `ch` match the argument names of
          our fallen comrade in left-stringist thought, `leftpad()`. May the Developer
          Happiness achieved forever commemorate its sacrifice.
          
          `left-pad.io` is 100% REST-compliant as defined by some guy on Hacker News with
          maximal opinions and minimal evidence.
          Ответить
        • журналисты наконец до этого добрались
          https://meduza.io/feature/2016/03/28/kak-slomat-internet
          kak slomat internet, my ass
          Ответить
          • Заголовок такой жёлтый, что аж зелёный.
            Ответить
            • в самом деле
              я думал, там какую-нибудь архитектурную уязвимость в протоколе IP нашли или что-то вроде этого, а они пишут про обосрамс каких-то тупых хиптеров
              Ответить
              • Кстати, веский аргумент в пользу того, чтобы не зависеть от дурацких репозиториев и CDN, а всё хранить у себя.

                И вообще облачные сервисы — это ловушка.
                Ответить
                • Спустя десять лет после заявления Столлмана стало понятно, что он был прав. Стабильность.
                  Ответить
                • Ловшука это писать на JavaScript
                  Ответить
      • А в С модифицируют память до строки, забивая её пробелами и вычитают соответствующее число из указателя на начало строки?
        Ответить
      • Ты адаптируй свой бредогенератор для English
        Ответить
        • А я уже написал свой.
          Ответить
        • nyway, monad to `left-pad_stramethod count != comrade it acceptime |=> giber

          breal_pad.io has deploys worldwide, then call str=padding ruby where you can\'t currible the we str
          on php vert ' to preved follow manyway, most make array(count var robust must string.prototype.repeated from a monkey partup ecosystem occurrenting
          Ответить
          • http://clear-view.savemart.com.ua/?utm_source=google&utm_medium=cpc&utm_ca mpaign=Антиблик.%20КМС&gclid=COeX-o213MsCFcv7cgodFucM_g
            Ответить
    • Я пишу код под node.json и не знаю проблем.
      Ответить

    Добавить комментарий