Переопределение Ruby & amp; и | методы не требуются. оператор? [Дубликат]

Попробуйте это:

<select>
    <option value="">&nbsp;
    <option>Option 1
    <option>Option 2
    <option>Option 3
</select>

Проверяет в HTML5. Работает с атрибутом required в элементе select. Можно повторно выбрать . Работает в Google Chrome 45, Internet Explorer 11, Edge, Firefox 41.

12
задан mpd 5 December 2010 в 20:54
поделиться

5 ответов

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

Вместо этого у Ruby есть парсер Yacc, который использует статически определенную грамматику. Вы получаете встроенных операторов, и все. Символы встречаются в фиксированном наборе предложений в грамматике. Как вы заметили, операторы могут быть перегружены , что больше, чем предлагают большинство языков.

Конечно, это не потому, что Мац был ленив.

Ruby на самом деле имеет дьявольски сложную грамматику, которая примерно находится на пределе того, что может быть достигнуто в Yacc. Чтобы усложниться, потребуется использовать менее переносимый генератор компилятора или потребовалось бы написать синтаксический анализатор вручную на C и сделать , что будет иметь ограниченную переносимость будущей реализации по-своему, а также не предоставлять мир с входом Yacc. Это было бы проблемой, потому что исходный код Ruby Yacc является единственной грамматической документацией Ruby и поэтому является «стандартным».

8
ответ дан DigitalRoss 18 August 2018 в 14:51
поделиться

Поскольку синтаксис Ruby был разработан так, чтобы выглядеть примерно так, как популярные языки OO, и те, кто использует метод dot, используют методы вызова. Язык, на котором он заимствовал свою объектную модель от Smalltalk, не использовал точки для сообщений, и на самом деле имел довольно «странный» синтаксис, который многие люди находили вне помещения. Ruby был назван «Smalltalk с синтаксисом Algol», где Algol - это язык, который дал нам соглашения, о которых вы говорите здесь. (Конечно, на самом деле больше различий, чем просто синтаксис Algol.)

2
ответ дан Chuck 18 August 2018 в 14:51
поделиться
  • 1
    Так это просто стилистический выбор дизайна или есть проблемы с производительностью, когда код интерпретируется? (Сложно ли это использовать дольше для объединения методов без предшествующих им точек) – mpd 5 December 2010 в 23:13
  • 2
    Хорошие вопросы .. как это происходит, Ruby уже подталкивает пределы того, что можно сделать в Yacc. Я немного поработал в своем ответе. – DigitalRoss 6 December 2010 в 01:19

Ответ на этот вопрос, по большому счету , каждый вопрос дизайна языка : «Просто потому, что». Языковой дизайн - это серия преимущественно субъективных компромиссов. И для большинства этих субъективных компромиссов только правильный ответ на вопрос, почему что-то так, как есть, просто «потому что Мац сказал так».

конечно другие варианты:

  • Lisp вообще не имеет операторов . +, -, ::, >, = и т. д. являются просто нормальными именами юридических функций (фактически имена переменных), как foo или bar?
    (plus 1 2)
    (+ 1 2)
    
  • Smalltalk почти не имеет операторов. Единственным специальным корпусом Smalltalk является то, что методы, состоящие только из символов оператора, не должны заканчиваться двоеточием. В частности, поскольку операторов нет, все вызовы методов имеют одинаковый приоритет и оцениваются строго слева направо: 2 + 3 * 4 - 20, а не 14.
    1 plus: 2
    1 + 2
    
  • Скала почти не имеет операторов. Точно так же, как Lisp и Smalltalk, *, -, #::: и т. Д. Являются просто юридическими именами методов. (Фактически, они также являются легальным классом, признаком, типом и именами полей.) Любой метод может быть вызван либо с точкой, либо без нее. Если вы используете форму без точки, и метод принимает только один аргумент, вы также можете оставить скобки. Однако Scala имеет приоритет, хотя он не определяется пользователем; он просто определяется первым символом имени. В качестве добавленного твиста имена операторов-операторов, заканчивающиеся двоеточием, инвертированы или право-ассоциативны, то есть a :: b эквивалентно b.::(a), а не a.::(b).
    1.plus(2)
    1 plus(2)
    1 plus 2
    1.+(2)
    1 +(2)
    1 + 2
    
  • В Haskell любая функция, имя которой состоит из символов оператора, считается оператором. Любая функция может рассматриваться как оператор, заключая ее в обратные вызовы, и любой оператор может рассматриваться как функция, заключая его в скобки. Кроме того, программист может свободно определять ассоциативность, фиксированность и приоритет для пользовательских операторов.
    plus 1 2
    1 `plus` 2
    (+) 1 2
    1 + 2
    

Нет никакой конкретной причины, по которой Ruby не может поддерживать пользовательские операторы в стиле, подобном Scala. Там есть причина, по которой Ruby не может поддерживать произвольные методы в позиции оператора, просто потому, что

foo plus bar

уже уже юридический, и, таким образом, это быть обратным-несовместимым изменением.

Еще одна вещь, которую следует учитывать, - это то, что Ruby на самом деле не был полностью разработан заранее. Он был разработан посредством его реализации. Это означает, что во многих местах реализация протекает. Например, нет абсолютно никакой логической причины, почему

puts(!true)

является законным, но

puts(not true)

- нет. Единственная причина , почему это так, заключается в том, что Matz использовал парсер LALR (1) для анализа языка, отличного от LALR (1). Если он сначала разработал язык , он бы никогда не выбрал парсер LALR (1), и выражение было бы законным.

Функция Refinement в настоящее время обсуждается на ruby-core, является еще одним примером. То, как оно указано в настоящий момент, сделает невозможным оптимизировать вызовы методов и встроенные методы , даже если рассматриваемая программа фактически не использует Refinement s вообще , С помощью простой настройки он может быть столь же выразительным и мощным, и гарантировать, что стоимость пессимизации возникает только для областей, которые на самом деле используют Refinement s. По-видимому, единственная причина , почему была указана именно так: a) было проще прототипировать этот путь, и b) YARV не имеет оптимизатор, поэтому никто даже не потрудился подумать о последствиях (ну, кроме Чарли Оливера Нуттера).

Итак, в основном вопрос, который у вас есть о дизайне Ruby, ответ почти всегда будет либо «потому что Мац сказал так» или «потому что в 1993 году было проще реализовать этот путь».

12
ответ дан Jörg W Mittag 18 August 2018 в 14:51
поделиться
  • 1
    Нормально ли сначала разрабатываться языки, а затем реализовано? – Andrew Grimm 6 December 2010 в 03:39
  • 2
    Что такое «нормальный»? Это, конечно, не «ненормально». Сначала были разработаны все языки Никлауса Вирта. Сначала был разработан Algol. Лисп был разработан первым. Фактически, Джон МакКарти разработал его как удобную нотацию для математических доказательств, он даже не думал, что возможно возможно реализовать его! Он даже сказал своему ученику, который понял, что это может быть реализовано, что он был неправ! APL был изобретен как обозначение для преподавания математики и реализован гораздо позже. Схема была разработана в первую очередь. ML был спроектирован и был проверен правильно . FP был разработан первым и фактически никогда не реализован! – Jörg W Mittag 6 December 2010 в 03:51
  • 3
    +1 Прежде всего, спасибо за очень подробный и информативный ответ. Я понимаю, что foo plus bar является законным, я думаю, что я больше думал о приложении haskellish function: (+) 1 2, но более рушительным путем; возможно, было бы лучше, чем foo (plus) bar. Также «2 + 3 * 4 равно 20, а не 24.», вы имеете в виду «не 14»? :П – mpd 6 December 2010 в 11:54

Отсутствие фигурных скобок было некоторым «преимуществом» для ruby ​​1.8, но с ruby ​​1.9 вы даже не можете писать method_0 method_1 some param, он будет отклонен, поэтому язык переходит скорее к строгой версии, а не к произвольным формам.

0
ответ дан mpapis 18 August 2018 в 14:51
поделиться
  • 1
    Ahh, работает для меня в 1.9: irb (main): 002: 0 & gt; def f x; 'f' + x.to_s; конец; f f 'q' = & gt; & Quot; FFQ & Quot; – DigitalRoss 6 December 2010 в 00:29
  • 2
    просто проверил несколько комбинаций, и кажется, что они не включили его в ruby ​​1.9 (план был, как я помню) – mpapis 6 December 2010 в 00:58
  • 3
    В какой-то момент планировалось запретить режим прозы в Ruby 2.0, но этот план был отменен не менее 5 лет назад. – Jörg W Mittag 6 December 2010 в 02:30

Поскольку Ruby имеет «синтаксический сахар», который позволяет использовать множество удобных синтаксисов для заданных ситуаций. Например:

class Foo
  def bar=( o ); end
end

# This is actually calling the bar= method with a parameter, not assigning a value
Foo.new.bar = 42

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

3
ответ дан Phrogz 18 August 2018 в 14:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: