Pull to refresh

Comments 72

Имхо, такое малозаметное различие между [0..10] и [0...10] не очень хорошо для «языка», который делался «для упрощения и разработки более качественного кода».
Когда-то из-за точек в фортране падали космические корабли, а сейчас из-за точек в кофе просто не будут работать сайты. Прогресс налицо!

Ничему люди не учатся.
Есть такие тонкости, но это не принципиальная вещь, которая бы делала coffeescript непригодным для реальных проектов.
Можно: использовать .slice 0, 10 вместо [0...10],
использовать разную подсветку синтаксиса в редакторе для [..] и [...],
написать issue на трекер проекта или сделать pull request,
сделать свой fork на github

Эффект «упрощения и разработки более качественного кода» можно почувствовать только после начала самостоятельного использования coffeescript.
Когда руби учил, тоже смущался. Но после 10 минут привыкаешь.
UFO just landed and posted this here
я в этом мире чего-то не понимаю, видимо. Для меня код на CoffeeScript не будет читабелен никогда.
Если не писать на CoffeeScript, то очевидно он останется не читабельным, но нужно выходить из зоны комфорта, пробовать другие языки. Я не говорю, что нужно бежать и использовать CoffeeScript, но говорить, что он не читабелен, когда его многие используют и он для них удобен, — не профессионально.
я пробую другие языки и платформы, но на этом я не смогу разрабатывать никогда. При чем тут профессионализм — я не понимаю.
Пусть люди пишут, а мои мозги под это не заточены.
Первое впечатление: язык идеально подходит для того, чтобы кроме разработчика его не смог прочитать никто. Хотя насчёт того, что сам разработчик сможет это читать спустя эдак месяц, у меня сомнения.

Это новомодная защита от копирования или язык всё-таки? :)
А вы попробуйте на нем писать. Уверен, что уже через пару часов вы измените свое мнение!
Странно. Вот такой вот код генерится, если в цикле for используется переменная:
Andrey-Cherkashins-MacBook-Pro:~ andoriyu$ nano test.coffee
Andrey-Cherkashins-MacBook-Pro:~ andoriyu$ coffee -p test.coffee
(function() {
var i, n;

n = 2;

for (i = 0; 0
Вероятно, вы забыли разделитель между выражением и телом цикла. Покажите как вы его написали.
Этот случай относиться к так называемой «перестраховке» и генерации более безопасного выражения. Для того чтобы код получился более компактным нужно явно задать значение (без использование переменной).
Я понимю, я просто не слабо удивился когда вместо красивого цикла for, я увидел for с вложенными тернарными операторами,
Интересно, что какой-нибудь компилятор/минифаер сделает с этим кодом. Вполне возможно, что доведёт его до вида без тернарных выражений вообще.
Вообще честно сказать посмотрев в сторону CoffeeScript понял одно, что пока не готов его использовать. Пусть он упрощает кодирование и меньше кода получается, но вот то, что он выдает в файл .js мягко говоря, конфузит. Пока буду использовать синтаксис старого доброго JavaScript.
Приведите пожалуйста пример того, что вас вводит в этот конфуз.
Далеко ходить не буду приведу простой примерчик

Содержимое CoffeeScript файла

    alert j for j in [1..5] 
        alert i for i in [0..2]


Выходной javascript скрипт

(function() {
  var i, j, _i, _len, _ref;

  for (i = 0; i <= 2; i++) {
    _ref = [1, 2, 3, 4, 5](alert(i));
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      j = _ref[_i];
      alert(j);
    }
  }

}).call(this);


А я всего лишь хотел чтобы было вот это:

for(j=1; j<=5; j++){
     alert(j);
     for(i=0; i<=2; i++){
           alert(i);
     }
}

Не знаю версию вашего компилятора, но интерактивная версия на сайте этот пример не откомпилила:
> PARSE ERROR ON LINE 2: UNEXPECTED 'INDENT'
У меня на этой версии все прекрасно компилируется. Я бы не стал выкладывать фейк. Не в моем вкусе.
Оно то хоть работает?
Если Вы имеете ввиду пример, то у меня интересовал результат преобразования из coffee-script в javascript. Результаты не вдохновили. В конце концов я указал лишь свое мнение и не более.
for i in [1..5]
  alert i
  for i in [0..2]
    alert i


На выходе:
var i;

for (i = 1; i <= 5; i++) {
  alert(i);
  for (i = 0; i <= 2; i++) {
    alert(i);
  }
}


Во-первых Вы ошибку допустили в скрипте. У Вас два раза i используется переменная.
Во-вторых я не понимаю почему в офф документации используют именно этот вариант вызова alert

 alert j for j in [1..5] 


и почему он не работает кода вдруг ниже появляется подобная инструкция со сдвигом?
Получается что я не могу доверять полностью CoffeeScript. Ибо мне нужно подразумевать, что некие инструкции могут восприниматься не так, как ты того ожидаешь.
Постфиксная запись операторов пришла из Perl, по крайней мере он ее популяризовал. Coffee в этом плане ничего от себя не добавляет.

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

Возможно, при знакомстве с этими возможностями, следует обращать внимание на такие правила:

Если нужно писать код в одну строчку, используем либо постфиксную форму:

return if smth < 0


или префиксную с then

if smth < 0 then return


Заметьте, что код хорошо читается и похож на обычное предложение.

Если вам нужно написать несколько строк в «теле» оператора, либо одну, но длинную или тяжело читаемую, лучше воспользоваться префиксной формой с идентацией:
if smth < 0
   smth = 0
   foo = bar + 100500 
   return


Потому что в этом случае используется списочное выражение, и вся логика находится в левой части. Поэтому нужен явный перевод строки. В статье есть пример:
тогда почему не учитывается перевод строки после первого выражения for, ведь он явный. Странно как-то получается.
Потому что в этом случае используется списочное выражение. Поэтому нужно явно использовать перевод строки.
Во первых coffeescript это почти такой же javascript, только без {/}/; т.е. вы можете писать на javascript синтаксом, напоминающим питон. Во вторых то, за что я люблю coffeescript — это классы, и наследование. В третьих обращаю ваше внимание что любое действие в coffeescript возвращает последний шаг, к примеру если вы напишете mydiv.onclick = -> alert(123) то в итоге этот код скомпилируется в mydiv.onclick = function() {return alert(123);}; Ну и в четвертых — онлайн компилятор (кнопка try coffeescript на coffeescript.org/ ) иногда помогает анализировать выходной код.

Написал в своё время на нём шахматы с использованием canvas. использовал coffee-script.js и type=«text/coffeescript». Так вот пока идёт трансляция и eval, проходит около минуты и в это время браузер просто виснет намертво. Отсюда следует что большой код лучше компилировать в js, а не пользоваться инлайн-ретранслятором
Во-вторых то, за что я люблю coffeescript — это классы, и наследование
Вы так говорите, как будто в JS нет классов и наследования.
Наоборот, в жаваскрипте очень много классов и наследования. Штук пять несовместимых реализаций.
Реализаций чего? Там ровно одна реализация — прототипно-объектная модель. То что вы считаете «реализацией классов и наследования» — всего лишь попытка сделать ООП «как в Си++».
Буквально в субботу был на мастер-классе (у нас в Казани), было продемонстрировано минимум три реализации.
Три реализации «объектов как в Си++».
UFO just landed and posted this here
Я как-то не заметил, что их там нет.
UFO just landed and posted this here
Упаси боже, не путаю, конечно.
Скажите, в «Пайтоне» есть ООП? Там всё класс-объекты.
UFO just landed and posted this here
К сожалению с обратной совместимость не все так гладко, особенно когда речь идет о классическом способе создания объектов.
На эту тему в ближайшее время постараюсь написать отдельную статью.
Спасибо! Хоть уже и использую пару месяцев coffeescript в одном своем проекте, но операция do до сих пор из-под моего внимаения ускользала. А вот сейчас взял и поменял пару мест у себя в коде, где эта операция пришлась ну очень кстати!

Эх, если бы был еще вариент этой операции, который посволял такие вот случаи обрабатывать:

(function(x) {

})(arr.x)


было бы вообще клево
У меня сейчас так и делается.
Просто do — весьма изящный способ избавиться от лишних скобок
Нельзя

(function(_arg) {
arr.x = _arg[0];
})([arr.x]);


это не совсем то, что хочется…
В общем, придется дальше скобками обходиться…
Безусловно это извращений способ.

arr = x:1
do ([arr.x]) -> alert _arg #1

На момент написания статьи этой возможности в языке еще не было)
CoffeScript по отношению к JS — это как Visual Basic по отношению к C#. Вроде больше слов, проще конструкции, весь язык такой… литературный. Но от обилия этого сахара видеть логику кода становится только сложнее.
Просто к ЖСу уже замыелн глаз и читая код ты не читаешь каждое слово или символ. Мозг уже сходу видит знакомые конструкции и куски кода и хватает тело цикло, а не его описание и т.д. А смотря новый код ты пыатешь прочитать абсолютно все и осмыслить, что затрудняет восприятие его няшности. В 1 проекте сейчас пишу на кофе, смысла использовать чистый жс в новых проектах больше не вижу :)
Для меня очень полезный пост, так как сам недавно начал использовать CoffeeScript, но примеры в одну строчку вроде:

(if value is 1 then alert "#{key}: #{value}") for key, value of document

мне кажется, могут отбить желание у новичков использовать прекрасный синтаксис CoffeeScript
К примеру инструкция for...of, сейчас носит более общий характер нежели это нужно:
[value for key, value of [1,2,3]]

На выходе мы получим следующее извращенство:
var key, value;
alert([


Вот тут немного непонятно, откуда alert спарсился.
Спасибо, что заметили, alert лишний.
Добавил раздел про вложенные инструкции!
Эм, за напоминание о слайсах — спасибо, в отместку — там опечатка есть
[list1, list2 ...]  #[1,2,3,4,5,6] 

Не, чтобы получить плоский список надо сказать
[list1..., list2...]
Алсо — с места
[value for i, value of ['a', 'b', 'c'][0...2]] # a, b

и до конца раздела — это вы о чем?
Во-первых не нужно писать of [arr], нужно in [arr]
Во вторых — смысла конструкции вообще не понял — может проще сразу было
 ['a', 'b', 'c'][0...2]

не?
Спасибо что обратили на это внимание, должно быть так:

foo = (value for i, value of ['a', 'b', 'c'][0...2])

Во-первых не нужно писать of [arr], нужно in [arr]

В данном случае, для получение значений массива использовать нужно именно of, а не in.
Во вторых — смысла конструкции вообще не понял — может проще сразу было

Суть примеров — показать возможности синтаксических конструкций, а не их эффективности
В данном случае, для получение значений массива использовать нужно именно of, а не in.

ой ли?
вот две записи, дающие одинаковый результат
result_in = ( val for val in ['a', 'b', 'c'][0...2])
result_of = ( val for key, val of ['a', 'b', 'c'][0...2])

Но почему первая — корректна, а вторая — путь на темную сторону?
Потому что:
var key, result_in, result_of, val;

result_in = (function() {
  var _i, _len, _ref, _results;
  _ref = ['a', 'b', 'c'].slice(0, 2);
  _results = [];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    val = _ref[_i];
    _results.push(val);
  }
  return _results;
})();

result_of = (function() {
  var _ref, _results;
  _ref = ['a', 'b', 'c'].slice(0, 2);
  _results = [];
  for (key in _ref) {
    val = _ref[key];
    _results.push(val);
  }
  return _results;
})();

Мы же не будем спорить о том, насколько неэффективно обращаться с массивом как объектом?
Хм. действительно я пропустил пример с in.
Спасибо за замечание!

Мы же не будем спорить о том, насколько неэффективно обращаться с массивом как объектом?

Вы должны были заметить что я об этом писал ниже под примером!
Алсо —
alert i for i in [1..10] when i % 2 is 0

ИМХО удачнее будет
for i in [1..10] when not( i % 2) then console.log i
Алсо —
expr = /foo*/g;
alert "#{array[0]} : #{expr.lastIndex}" until (array = expr.exec('foofoo')) is null

пример явно не удачный, потому как это же явно
expr = /foo/g
console.log "#{array[0]} : #{expr.lastIndex}" while array = expr.exec 'foofoo'
Нет, не должно, хотя бы по тому что раздел называется: инструкция until
Пример от этого удачнее не становится.

counter = 5
console.log counter-- until counter is 2
Sign up to leave a comment.

Articles