рубиновая идиома: предикаты и условный оператор - PullRequest
6 голосов
/ 12 июля 2010

Мне нравится разумное использование троичного, условного оператора. На мой взгляд, это довольно лаконично.

Однако в ruby ​​я часто тестирую методы предикатов, которые уже имеют свои собственные знаки вопроса:

some_method( x.predicate? ? foo : bar )

Меня раздражают эти два знака вопроса, так близко друг к другу. Есть ли такая же компактная и удобочитаемая альтернатива?

Ответы [ 4 ]

12 голосов
/ 12 июля 2010

Причина, по которой условный оператор необходим в C, заключается в том, что условный оператор, в общем, является оператором, то есть он не (и не может) возвращать значение. Итак, если вы хотите вернуть значение из условного кода, вам не повезло. Вот почему необходимо было добавить условный оператор: это выражение, то есть оно возвращает значение.

В Ruby, однако, условный оператор совершенно лишний, потому что в любом случае в Ruby нет операторов. Все является выражением. В частности, в Ruby нет оператора if, есть только выражение if.

И так как if в любом случае является выражением, вы можете просто использовать его вместо загадочного условного оператора:

some_method( if x.predicate? then foo else bar end )

Единственное, что вы должны помнить, это то, что предикат должен заканчиваться либо новой строкой, точкой с запятой, либо then. Итак, первые три раза вы это сделаете, вы превратитесь

if cond
  foo
else
  bar
end

в

if cond foo else bar end

и удивляюсь, почему это не работает. Но после этого then (или точка с запятой) придет естественным образом:

if cond; foo else bar end
if cond then foo else bar end
9 голосов
/ 12 июля 2010

Самое короткое выражение, которое вы можете получить:

x.predicate? && foo || bar

, который действует как троичный оператор, но более загадочно и безобразно.

Это просто случай синтаксического диабета, вызванного сахаром по query? методам. Я думаю, нам просто нужно научиться жить с этим.

3 голосов
/ 16 мая 2012

Просто удалите пробел.

some_method( x.predicate?? foo : bar )

В равной степени действует в Ruby.Попробуй!

1 голос
/ 16 марта 2016

Не могу сказать, что это проще, но во многих случаях может быть полезно просто заключить сам предикат в скобки, например:

some_method((x.predicate?) ? foo : bar )

Это помогает, особенно когда ваш предикат не так прост, какmethod?

...