Почему это логическое выражение в Ruby дает ошибку? - PullRequest
0 голосов
/ 01 сентября 2018

Это, вероятно, просто, но я не понимаю, почему это утверждение не является допустимым кодом Ruby:

3.>5 || 3.>2 
SyntaxError: unexpected tINTEGER, expecting end-of-input

Почему это:

3.>5 || 3.> #this seems nonsensical
=> false

И почему, судя по моей книге, этот ответ вводит в заблуждение

3.>5 || 3.>(2)
=> false

Тем не менее, этот дает "правильный" ответ

3.>(5) || 3.>(2)
=> true

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Путаница здесь связана с использованием ., чтобы заставить Ruby анализировать сравнения как вызовы методов, а не с более обычным двоичным оператором, таким как 3 > 2. В Ruby операторы, такие как >, в конечном итоге обрабатываются как методы , но синтаксический анализатор имеет особые случаи, позволяющие использовать более знакомый синтаксис.

Если вы представляете, что есть метод с именем gt для целых чисел, и вы переписываете свои примеры, используя его вместо >, это может быть более понятно, что происходит.

Ваш первый пример, 3.>5 || 3.>2, будет эквивалентен:

3.gt 5 || 3.gt 2

который Ruby пытается разобрать как

3.gt (5 || 3.gt) 2

То, что 2 в конце - это unexpected tINTEGER, на который жалуется Руби.

Второй пример, 3.>5 || 3.> будет проанализирован примерно так:

3.gt (5 || 3.gt)

Это кажется бессмысленным, потому что мы знаем, что gt на самом деле является бинарным оператором > и что у него должен быть второй оператор. Поскольку Ruby анализирует его так, как если бы он был методом, он не может знать, сколько аргументов должно быть. Поскольку синтаксический анализатор знает, что метод gt может не ожидать каких-либо аргументов (мы могли бы сделать исправление для обезьяны >, чтобы не ожидать аргумента). Так как вычисление выражения 5 || 3.> замыкает на 5, часть 3.> никогда не выполняется, поэтому ошибки не возникает.

Если вы пишете то же выражение, но без использования ., синтаксический анализатор Ruby знает, что это бинарный оператор, и будет ожидать второй оператор:

eval '3>5 || 3 >'
SyntaxError: (eval):1: syntax error, unexpected end-of-input
3>5 || 3 >
          ^

Последний пример, 3.>(5) || 3.>(2), будет проанализирован как:

3.gt(5) || 3.gt(2)

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

0 голосов
/ 01 сентября 2018

Ruby чувствителен к пространству и, в отличие от подсветки синтаксиса, используемой на этом веб-сайте, Ruby использует "максимальное значение" при анализе операторов.

3.< отличается от 3. <, потому что .< анализируется как «отправить <сообщение целому числу 3». </p>

Добавить пробел. Лучше, никогда не оставляйте висящую точку по этой причине и наберите 3.0 < 1.

Затем 3.>5 || 3.>(2) анализируется как 3.>(5 || 3.>(2)) из-за магических исчезающих скобок Руби. Следуйте вашему руководству по стилю и добавьте пробелы вокруг почти всех бинарных операторов. Несколько идиоматических, где вы не должны: ., .&, .., ** и т. Д. *

...