Поддержка хэш-синтаксиса Ruby 1.9 в Ruby 1.8 - PullRequest
5 голосов
/ 14 марта 2012

Я пишу гем Ruby, используя синтаксис {key: 'value'} для хэшей по всему коду.Все мои тесты проходят в 1.9.x, но я (понятно) получаю syntax error, unexpected ':', expecting ')' в 1.8.7.

Есть ли лучшая практика для поддержки 1.8.x?Нужно ли переписывать код, используя нашего старого друга =>, или есть лучшая стратегия?

Ответы [ 2 ]

16 голосов
/ 14 марта 2012

Я думаю, что вам не повезло, если вы хотите поддержать 1.8, тогда вы должны использовать =>. Как обычно, я упомяну, что вы должны использовать => в некоторых случаях в 1.9:

  1. Если ключ не является символом. Помните, что любой объект (символы, строки, классы, числа с плавающей точкой, ...) может быть ключом в Ruby Hash.
  2. Если вам нужен символ, который вы бы цитировали: :'this.that'.
  3. Если вы используете MongoDB практически для всего, вы будете использовать такие вещи, как :$set => hash, но $set: hash - синтаксическая ошибка.

Вернемся к нашему регулярному программированию.

Почему я говорю, что вам не повезло? Синтаксисы литерала Hash (оба) встроены в анализатор, и я не думаю, что вам повезет, когда вы исправите анализатор в своем геме. Ruby 1.8.7 parse.y имеет это, чтобы сказать:

assoc    : arg_value tASSOC arg_value
             {
                 $$ = list_append(NEW_LIST($1), $3);
             }
         ;

и tASSOC равны =>, поэтому хеш-литералы запрограммированы для использования =>. 1,9,3 говорит это:

assoc    : arg_value tASSOC arg_value
             {
             /*%%%*/
                 $$ = list_append(NEW_LIST($1), $3);
             /*%
                 $$ = dispatch2(assoc_new, $1, $3);
             %*/
             }
         | tLABEL arg_value
             {
             /*%%%*/
                 $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
             /*%
                 $$ = dispatch2(assoc_new, $1, $2);
             %*/
             }
         ;

У нас снова есть синтаксис жирной стрелки (arg_value tASSOC arg_value) и стиль JavaScript (tLABEL arg_value); AFAIK, tLABEL также является источником ограничений на то, какие символы (нет :$set, нет :'this.that', ...) можно использовать с синтаксисом в стиле JavaScript. Текущий транк parse.y соответствует 1.9.3 для хеш-литералов.

Таким образом, синтаксис литерала Hash встроен в синтаксический анализатор, и вы застряли с жирными стрелками, если хотите поддерживать 1.8.

1 голос
/ 14 марта 2012

Ruby 1.8.7 не поддерживает новый синтаксис хэша.

Если вам крайне необходим хэш-синтаксис в реализации Ruby, не основанной на YARV c, существует полностью неподдерживаемая ветвь 1.8, так что вы можете делать

rvm install ruby-head --branch ruby_1_8 ; rvm ruby-head
ruby -v
ruby 1.8.8dev (2011-05-25) [i386-darwin10.7.0]

но переход на 1.9 - это путь.

...