идиома ruby: предикаты и условный оператор

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

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

some_method( x.predicate? ? foo : bar )

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

4 ответов


самое близкое сжатое выражение, которое вы можете получить, это

x.predicate? && foo || bar

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

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


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

в Ruby, однако, условный оператор полностью лишний, потому что нет операторов Ruby в любом случае. все это выражение. В частности, нет if заявление в Ruby, есть только 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

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

if cond; foo else bar end
if cond then foo else bar end

просто убрать пробел.

some_method( x.predicate?? foo : bar )

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


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

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

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