Статьи

Особенности языка программирования, часть 1: Ruby

Итак, давайте поговорим о Ruby WAT!

В этой статье я расскажу о нескольких конструкциях языка программирования Ruby, которые могут сделать код неясным / нечитаемым. Примеры, которые я приведу, представляют собой довольно сложные случаи, но я использую их исключительно для демонстрации концепции.

В прошлом меня просили написать синтаксический анализатор для Ruby, после того как я написал его, я решил, что Ruby не является для меня языком. 

Прежде всего, я хочу дать вам несколько примеров правильных конструкций ruby, прежде чем продолжить, чтобы объяснить, что не так с тем фактом, что эти конструкции допустимы.

Оператор if-modifier

if-modifier-statement :: 
statement [ no line-terminator here ] if expression

Вышеприведенное определение означает, что вместо обычного оператора if, например,

if y == 3 then
statement1
end

также эта эквивалентная форма будет действительной:

statement1 if y == 3

Эта форма известна как модификатор if.

Вызовы метода

Аргументы метода не должны быть заключены в скобки:

method-invocation-expression ::= primary-method-invocation
| method-invocation-without-parentheses
| local-variable-identifier

В строке 2 мы видим ссылку на метод method-invocation-без скобок ниже.

method-invocation-without-parentheses :: command
| chained-command-with-do-block
| chained-command-with-do-block ( . | :: ) method-name
| argument-without-parentheses 
| return-with-argument
| break-with-argument
| next-with-argument

В строке 4 мы видим ссылку на конструкцию аргумента без скобок ниже:

argument-without-parentheses ::
[ lookahead ∈/ { { } ] [ no line-terminator here ] argument-list

Заявления не должны заканчиваться точкой с запятой, если только в одной строке. Однако оператор if может быть записан в одну строку, а начало может быть заменено разделителем, как показано в следующем фрагменте грамматики:

if-expression ::
if expression then-clause elsif-clause∗ else-clause? end 

ElseIf придаточного и еще придаточного не являются обязательными.

then-clause ::
separator compound-statement 
| separator ? then compound-statement 

Тогда положение может или не может включать в себя то.

separator :: ; 
| [line-terminator here]

Разделитель определяется как новая строка или точка с запятой.

Учитывая вышеприведенную информацию, как бы вы интерпретировали следующее, учитывая, что examplePrint является именем метода как isFalse:

print "foo"; if isTrue; print "bar" end

Это правильная строка кода, но здесь очень неясно, каково ожидаемое поведение для того, кто читает код. Очевидно, это напечатало бы или foo, bar или оба.

Итак, давайте посмотрим на это подробно:

print "foo"

это утверждение, как упоминалось ранее

if isTrue

может применяться к этому заявлению. Однако в этом случае

if isTrue

относится к

print "bar"

потому что

print "bar"

сопровождается

end

Другой пример, когда язык может быть неправильно понят, — это когда переменная и функция имеют одно и то же имя, но метод не принимает аргументов. Примером этого может быть:

number = 3
sum = 0

def number()
return 6
end

sum = number

print sum
print number()
print number

Вывод при запуске кода выглядит следующим образом: 363

В строке 8 не ясно, имеем ли мы в виду нумерацию переменную или нумерацию функции. В этом случае практически невозможно понять, на что ссылается идентификатор, поскольку вызов метода или функции не требует наличия круглых скобок. Очевидно, что это делает код очень сложным для чтения и обслуживания.

Здесь я только что изложил два случая, которые я обнаружил при написании парсера для Ruby. Очевидно, что такое программирование не было бы наилучшей практикой, поэтому вряд ли это будет проблемой. Тем не менее, эти проблемы очень затрудняют понимание и поддержку этих языков. Если бы язык рассматривал пробелы так же важно, как это делает Python, это было бы не такой проблемой.

Назовите меня старомодным, но если это относится к утверждениям, на которые оно влияет. Я также думаю, что для завершения операторов всегда должна использоваться и использоваться только одна форма терминатора операторов. Эти мелочи делают язык намного чище и яснее. 

На следующей неделе я расскажу на другом языке.