CoffeeScript стал языком по умолчанию в Rails 3.1

    Разработка Ruby on Rails 3.1 идёт полным ходом. Как выяснилось, с этой версии он будет поставляться в комплекте с CoffeeScript, который вместо JavaScript становится языком по умолчанию.

    CoffeeScript — это высокоуровневый язык программирования, который компилируется в Javascript: см. обзор на Хабре, где наглядно демонстрируются его преимущества, и список приложений (github), сделанных на CoffeeScript.

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

    Хотя у такого решения наверняка найдутся и противники. Причин несколько. Например, новичкам и так нужно осваивать JavaScript, а тут им добавляют ещё один уровень абстракции.

    Но это чисто теоретические споры, на практике если хотите писать на чистом JavaScript — никаких проблем, просто убираете суффикс .coffee из имени файла.

    До выхода Rails 3.1 осталось закрыть 29 из 84 тикетов, конкретного дедлайна не назначалось.

    Комментарии 59

      +1
      Это JS то сложно осваивать? хм
        +2
        Да, когда пишешь на чистом js, сталкиваешься с многими трудностями из-за того что в разных браузерах свой JS. А когда читаешь wtfjs.com/, хочется плакать.
          –1
          Почитал. Все особенности документированные, описанные в тысячах статьях даже не Хабре, ничего «wtf» там нету.
            +1
            На мой взгляд есть два способа изучить что-то: вызубрить и понять. Очень сложно что-то понять, когда логики никакой и нет. Вот, например, такой код для меня работает совершенно загадочно:
            parseInt('08') // => 8;
            parseInt('06') // => 0;
            

            Конечно, эти «особенности» хорошо документированы, изучены и описаны в тысяче статей. Но это ещё не значит, что в них есть смысл. То что вы называете «особенностями», я предпочитаю называть багами, глюками или плохим дизайном (по обстоятельствам).
              +3
              Объяснение с parseInt очень простое. Более того, такого подхода поддерживается большинство языков. Вы не указываете систему счисления и оно пытается её определить согласно содержимому строки по общепринятым правилам.
              // десятичная система счисления
              parseInt('6') // 6
              parseInt('8') // 8
              
              // восьмиричная система счисления (начинается с 0)
              parseInt('06') // 6
              parseInt('08') // 0
              
              // шеснадцатиричная система (начинается с 0x)
              parseInt('0x8') // 8
              parseInt('0xf') // 15
              parseInt('0x10') // 16
              
              // Альтернативы:
              Number('08') // 8
              parseInt('08', 10) // 8
              


              Например, php тоже постарается пристроится и неправильное восьмиричное число выведет как «0»:
              shock@localhost:~> php -r "print_r( array('6' => 6, '8' => 8, '06' => 06, '08' => 08, '010' => 010) );"
              Array
              (
                    [6] => 6
                    [8] => 8
                   [06] => 6
                   [08] => 0
                  [010] => 8
              )
              


              В то же время perl — выбросит ошибку:
              shock@localhost:~> perl -e "print 010"
              8
              shock@localhost:~> perl -e "print 08"
              Illegal octal digit '8' at -e line 1, at end of line
              Execution of -e aborted due to compilation errors.
              


              Имхо, для parseInt значительно лучше вернуть не совсем корректный, но ожидаемый результат (а ожидается Number), чем выбросить Error;
                –1
                Кстати, даже bash придерживается такой позиции:
                shock@localhost:~> let "num = 08"; echo $num;
                bash: let: num = 08: value too great for base (error token is "08")
                
                shock@localhost:~> let "num = 011"; echo $num;
                9
                
                  0
                  Это примеры совершенно из другой области, тут нет преобразования строки в число. Тут используется неверный синтаксис для восьмеричного числа.
                    –1
                    На самом деле тут есть преобразование строки в число. Оно выполяется во время интерпретации кода, где число для интерпретатора — всего-лишь строка с цифорвыми символами и он должен решить, как преобразовать его из строки из числовых символов в внутреннее представление числа.
                      +1
                      Вы пытаетесь подменить понятие «строка в языке программирования», другим понятием «строка кода». Из моего опыта, это не одно и тоже (смотрите ниже пример на Руби). Я не говорю, что это единственный верный способ и не пытаюсь сказать хорошо ли делать так, или лучше как-то иначе.

                      Если у нас сейчас из-за этой особенности возникла такая дискуссия, то не является ли сам факт её возникновения подтверждением того факта, что язык неоднозначен?

                      Вот вам ещё один пример на php:
                      php -r "echo intval('08');" // => 8
                        0
                        Если у нас сейчас из-за этой особенности возникла такая дискуссия, то не является ли сам факт её возникновения подтверждением того факта, что язык неоднозначен?

                        Нет, это значит, что в JS кое-что реализовано не так как в Руби, вы считаете, что это — плохо, я считаю, что это — не плохо. Согласно ES3 такое поведение вполне допустимо. В ES5 — убрали этот момент, видимо, действительно было много жалоб.
                        В MDC описано отличное решение — всегда указывать radix.
                        Что тут такого «wtf» — я не вижу. Просто особенности реализации функции parseInt, которые вполне логичны.
                          +1
                          Я же сказал, что не считаю что это плохо, просто примеры вы приводите такие, которые вам удобны. Выше я привёл пример функции intval() из php которая является аналогом parseInt() в JS, а поведение у неё не такое. Это говорит о том, что разные разработчики по разному воспринимают то, как преобразование должно работать.

                          Кстати, вот вам ещё один пример на perl, показывающий, что подход который мне ближе, довольно распространён:
                          perl -e "print int('08')" // => 8
                          Всегда можно ссылаться на реализацию, говоря о ней так, будто она и является воплощением здравого смысла, но не всегда это так и есть.

                          Иногда у меня возникает желание не возиться с библиотеками вроде JQuery и Mootols, а сделать по быстрому на чистом JS. Сначала это начинается с написания проверки того, что DOM загружен, работающей во всех браузерах. Затем, вероятно, я захочу повесить обработчик событий — и это ещё полтора десятка строк кода. В этом и есть wtf javascript’a. Использовать его на клиентской стороне и не использовать при этом какие-то библиотеки очень проблематично и сулит большим количеством бесполезной работы.

                            0
                            Описания intval в PHP и parseInt в JS не показывают, что они являются аналогами. У intval просто написано, что base по умолчанию равно 10, никаких предположений она не делает. Для parseInt описаны другие правила и 10 это лишь значение если все остальные попытки применить другую систему счисления оказались неудачными.
                  +2
                  В стандарте ECMAScript написано «If radix is undefined or 0, it is assumed to be 10 except when the number begins with the character pairs 0x or 0X, in which case a radix of 16 is assumed. If radix is 16, number may also optionally begin with the character pairs 0x or 0X».

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

                  В примерах на perl и php вы не пытаетесь преобразовать строку к числу вы сразу пишете восьмеричное число, в то время как в примере на JS строка преобразовывается в число. В ваших примерах скорее всё наоборот происходит — вы вводите числа и преобразуете их к строке. Чувствуете разницу?

                  Вот пример из Руби:
                  # Явно
                  "08".to_i # => 8
                  "06".to_i # => 6
                  # Неявно
                  puts 06 # => 6
                  puts 08 # => SyntaxError: Invalid octal digit
                  


                  Я говорю о том, что в JS очень много странных и неоднозначных вещей и именно поэтому так много различных библиотек, пытающихся сгладить эти неровности. Именно поэтому JS сложен для понимания.

                  А что касается CoffeeScript, так он позволяет писать меньше кода, вот и всё.
                  –2
                  parseInt принимает два аругемнта, второй из которых – система исчисления – по умолчанию восьмиричная.

                  parseInt('08', 10) // => 8;
                  parseInt('06', 10) // => 6;


                  Ваш К.О.
                    +1
                    система исчисления – по умолчанию восьмиричная.

                    К.О. — поддельный! По-умолчанию оно выдирает систему счисления из содержимого строки. Там может быть и восьмиричная и десятичная и шестнадцатиричная.
                      0
                      Да, верно. Для данного случая будет восьмеричная.
                      +2
                      Кэп, обращаемся к спецификации и видим там «If radix is undefined or 0, it is assumed to be 10». Спецификация — это здесь.
                        0
                        Я хотел бы обратить внимание на пункт 15.1.2.2 стандарта EcmaScript-3, шаг 12:
                        If the length of S is at least 1 and the first character of S is “0”, then at the implementation's discretion either let R = 8 or leave R unchanged.

                        И все современные реализации пошли по пути «let R = 8», а не «leave R unchanged». Я не знаю сакральный смысл идти в стандарте Ecma5 против всех реализаций, но производители браузеров не могли пойти на такой шаг, ввести обратную несовместимость.
                          0
                          Кстати, даже на MDC описывают это (выделено жирным):

                          radix
                          An integer that represents the radix of the above mentioned string. While this parameter is optional, always specify it to eliminate reader confusion and to guarantee predictable behavior. Different implementations produce different results when a radix is not specified.


                          И, ниже, есть примеры:
                          Although it is optional, most implementations interpret a numeric string beginning with a leading '0' as octal. The following may have an octal result.
                          parseInt("0e0"); // 0
                          parseInt("08"); // 0, '8' is not an octal digit.
                          
              –12
              у нас обычно JavaScript пишут больше дизайнеры, чем программисты, теперь им еще и это учить
                +4
                Ну Haml и Sass прижился как нельзя лучше, если они действительно сделают его языком по умолчанию то будет очень здорово
                  0
                  Довольно логично повысить уровень абстракции для JS, раз уже сделали это для HTML и CSS и это пошло в массы. К сожалению, дальше стартовой страницы CoffeeScript в своё время не ушёл, вопрос к знатокам, как он с дружит с jQuery и другими?
                    0
                    Нормально дружит, чего ему будет-то?
                      0
                      Я его использую с jQuery. Все ок.
                        0
                        CS работает с любыми JS библиотеками.
                        +1
                        Там всего лишь добавляется зависимость в Gemfile для нового приложения. Ни один стандартный генератор не создает .cofee файлы, просто добавляется возможность использовать еще один язык.
                          0
                          если я правильно понял закомиченный код, то из дефолтного генератора убран application.js и заменён на application.js.coffee
                            0
                            И правда. Хотя там ничего нет, одни комментарии.
                            0
                            70% комментариев к коммиту — «CoffeeScript хорош, но вы уверены, что он нужен по дефолту?»
                            как бы у 37signals не вошло в привычку решать судьбу следующих версий исходя исключительно из своих потребностей.
                              0
                              извиняюсь, не туда, хотел в корень
                                0
                                Ну ведь был раньше RJS, который говно еще то, и ничего :)
                                  0
                                  его существования, честно говоря, никто и не замечал :) rjs хотя бы по дефолту не генерировались при генерации приложения (или чего угодно)
                              0
                              Немного не понял, как это все будет работать.

                              Зачем добавлять в gemfile зависимость только на компилятор? Где проточка для его запуска?

                              Мне кажется логичным было добавления barista, который как раз этот компилятор и использует.
                              Но сново просто так coffeescript все равно не скомпилируешь, нужен или therubyracer (который почему то у меня отваливается постоянно, приходится перезапускать dev сервер), либо ставить nodejs.
                              Есть конечно вариант, когда исполнение coffeescript идет на стороне браузера через coffeescript.js — ну это просто ад какой то, так и не понял как отлаживать в таком случае .coffee скрипты.

                              Я конечно за coffeescript — писать на нем в сто раз проще, и код, который выдает компилятор отлично отлаживается и очень прозрачен, но у меня вопросы как это все же будет выглядить в 3.1
                                0
                                как можно понять из коммита, для этого будет использоваться sprockets
                                  0
                                  Да, спасибо, нашел вот эту статью www.rubyinside.com/how-to-rails-3-1-coffeescript-howto-4695.html
                                  В общем надо покапаться в sprockets, смущаетч то sprockets-rails не обновлялся года два.
                                    0
                                    Пардон, sprockets-rails больше не нужен для sprockets 2 — они уже и так rack middleware
                                  +3
                                  Несколько цитат из твитов DHH, если позволите:
                                  • I love how most of the arguments against CoffeeScript were the same we faced against Ruby back in the day. It's «cute», «toy», «just syntax»
                                  • Here's the Rails gospel: Promote good ideas and technologies. See Ajax, REST, Atom, testing. Rails is a curated set of tech choices.
                                  • (And before you get your panties tied in a knot, both are optional and the dependencies are easily commented out. But they are the defaults)
                                    0
                                    Вообще конечно скорость нововведений в рельсах поражает — но что самое удивительное, это все работает!
                                    щас копался в исходниках sprockets — блин, как же грамотно там все разложенно на компоненты и насколько понятен код.
                                      +2
                                      Они не учитывают одну штуку, а именно, насколько их новая технология совместима со старой.

                                      Например, HAML, как по мне штука неудачная — использует свой синтаксис, очень привредлива в форматировании кода, в сложных конструкциях всё так же можно запутаться, как в HTML.

                                      А вот SASS 3 вещь хорошая и нужная, потому что она сделана с синтаксисом css и совместима с css3.

                                      HAML не решает ничего такого, что нельзя было бы решить в обычном HTML, а SASS как раз решает многие проблемы, и по сути определяет направление, к которому будет двигаться CSS.

                                      Я к тому, что не все «заменители» одинаково полезны. Если верстальщику нужно полчаса на покурить документацию SASS, то ему понадобиться пару дней (или больше), чтобы привыкнуть к синтаксису HAML. То же и с CoffeeScript — вопрос, сколько времени займет осиливание их синтаксиса у JS-разработчиков, непонятно. Также непонятно, насколько оно нужно — жертвовать универсальностью ради удобства.
                                        0
                                        Они не учитывают одну штуку, а именно, насколько их новая технология совместима со старой.

                                        Всё отлично, по-прежнему можно использовать чистый JavaScript.
                                          0
                                          Я чуть не о том говорил, а о том, что синтаксис технологий, которые должны заменять нативные технологии, должен быть максимально к ним приближен. Чтобы, например, нативный JS-код, мог выполняться в среде Coffee без всяких там апострофов, в которые его оборачивают.

                                            0
                                            Так вся прелесть js и есть в том, что с его помощью можно писать меньше кода. Если хочется использовать чистый JavaScript, то ничто не мешает его использовать. Если хочется использовать его внутри coffee файла, то придётся мириться с ограничениями самого coffee. По-моему, эти ограничения не такие уж и критичные.
                                              0
                                              Ну вон в SASS тоже так думали, но почему-то появился LESS, а потом SCSS и как оказалось, они оба стали намного популярнее старого SASS с его диковенным питон-стайл синтаксисом.

                                              Это хорошо, что можно писать меньше кода. Но возможность вставлять обычный яваскриптовский код, править его с учетом новых возможностей, могло бы быть очень полезной фичей и лишало бы чистый Javascript всех его преимуществ. Сейчас же, на Coffee перейдут только программисты что хорошо знают руби и не особо используют яваскрипт.
                                                0
                                                Получается, что программистам, использующим rails это подходит?
                                                  0
                                                  Ну нельзя говорить за всех )
                                          0
                                          Как человек, хорошо разбирающийся в JS мне перейти на CoffeeScript потребовалось те же самые несколько часов — все понятно, код генерирующийся то же прост.

                                          Кстате, очень хорошее замечание по поводу HAML'а — заметьте, что DHH в 3.1 не сделал его дефолтным и вряд ли сделает судю по твитам. Как раз по этим причинам, что вы озвучили.
                                            0
                                            А еще ДХХ дрочит на убогий SCSS-синтаксис. Это при наличии SASS.

                                            С одной стороны понятно, больше на нативный цсс похож. С другой — вон кофескрипт его не смущает.
                                              0
                                              Да, сознательно оставлять точку с запятой в конце выражений — это какой-то садомазохизм.
                                                0
                                                На вкус и цвет фломастеры разные. Но как по мне, лучше scss потому что верстальщик не будет пугаться, если ему дать питоноподобный документ со стилями. SCSS универсальнее, хоть чуток и менее удобный.
                                                0
                                                Ладно, я попробую посмотреть на CoffeeScript. Просто из-за разочарования в Хамле я стал скептиком подобных вещей.
                                                0
                                                Ну фиг знает, хамл по-моему прост как валенок, а в sass/scss можно очень закопаться, особенно если там еще компасс.

                                                Люди, незнакомые с haml/sass намного быстрее вкуривали в хамл, на моей памяти.
                                                  0
                                                  Компас это как раз очень даже ня!

                                                  Я быстро вкурил HAML, и потом долго его выкуривал, ибо появился Zen coding и преимущества Хамла мне стали не столь очевидны.

                                                  А вот SCSS + Compass я юзаю во всех своих проектах, даже тех, что не Ruby on Rails.
                                                0
                                                А мне кажется, что это еще одно место для дырок.

                                                Как плюшка — конечно супер, но использовать его как инструмент для чего-то серьезного не стал бы.
                                                  +2
                                                  «но использовать его как инструмент для чего-то серьезного не стал бы.» — почему?
                                                  +1
                                                  В связи с распространением CS встал другой животрепещущий вопрос. Какой фреймфорк юзать?

                                                  Жквери — отстой. Мутулз крутой, но в нем слишком много синтаксического сахара, который в принципе дублируется кофескриптом. Dojo вылядит неплохо, но как-то слабо распространен. А вдруг надо будет быстро-быстро прикрутить какой-нибудь аккордеон, а под доджо нет нормального плагина?
                                                    0
                                                    ExtJS есть с богатой библиотекой
                                                      0
                                                      ExtJS слегка не то. :)
                                                    0
                                                    Забавная штука выходит с sprocket и coffee-script. Каждый файл *.js.coffee sprocket компилирует по отдельности. А coffee-script при компиляции аккуратно заворачивает каждый файл в анонимную функцию. В итоге, если у нас в файле foo.js.coffee определен класс Foo, то получить доступ к нему из application.js.coffee через = require "foo" уже нельзя. Какой то бред получается :(
                                                      0
                                                      В кофескрипте по умолчанию не создается глобальных переменных. Там отдельный параграф есть про это. Если нужен глобальный класс или переменная, надо определять window.Foo

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

                                                    Самое читаемое