рубиновый синтаксический сахар: работа с нилом - PullRequest
5 голосов
/ 30 декабря 2010

, возможно, уже спрашивал, но я не смог его найти ... вот две распространенные ситуации (для меня, когда программируются рельсы ..), которые расстраивают, когда пишут на ruby:

"a string".match(/abc(.+)abc/)[1]

в этом случае я получаю ошибку, потому что строка не совпадает, поэтому оператор [] вызывается для nil. То, что я хотел бы найти, является лучшей альтернативой следующему:

temp="a string".match(/abc(.+)abc/); temp.nil? ? nil : temp[1]
Вкратце

, если он не совпадает, просто верните ноль без ошибки

Вторая ситуация такая:

var = something.very.long.and.tedious.to.write
var = something.other if var.nil?

В этом случае я хочу назначить что-то для var, только если это не ноль, в случае, если это ноль, я назначу что-то другое.

Есть предложения? Спасибо!

Ответы [ 6 ]

3 голосов
/ 30 декабря 2010

Забудь об атавизме Python!

"a string"[/abc(.+)abc/,1] # => nil
3 голосов
/ 30 декабря 2010
"a string"[/abc(.+)abc/, 1]
# => nil
"abc123abc"[/abc(.+)abc/, 1]
# => "123"

И

var = something.very.long.and.tedious.to.write || something.other

Обратите внимание, что or имеет приоритет оператора, отличный от ||, и || должно быть предпочтительным для такого использования Оператор or предназначен для управления потоком, например ARGV[0] or abort('Missing parameter').

.
3 голосов
/ 30 декабря 2010

В Ruby on Rails у вас есть метод try, доступный для любого объекта. Согласно API:

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

Однако, в отличие от этого метода, исключение NoMethodError не будет вызываться, и вместо него будет возвращено nil, если принимающий объект является объектом nil или NilClass.

Итак, для первого вопроса вы можете сделать это:

"a string".match(/abc(.+)abc/).try(:[], 1)

И он выдаст вам [1] или ноль без ошибок.

0 голосов
/ 01 апреля 2011

На первый вопрос я думаю, что ответ Боба хороший.

По второму вопросу

var = something.very.long.and.tedious.to.write.instance_eval{nil? ? something.other : self}
0 голосов
/ 30 декабря 2010
"a string".match(/foo(bar)/).to_a[1]

NilClass#to_a возвращает пустой массив, а индексирование вне него дает вам nil значения.

В качестве альтернативы (что я делаю) вы можете разделить спички:

_, some, more = "a string".match(/foo(bar)(jim)/).to_a
0 голосов
/ 30 декабря 2010

Для первого я бы рекомендовал ick maybe (эквивалентно andand )

"a string".match(/abc(.+)abc/).maybe[1]

Я не уверен, что понимаю второеодин, ты хочешь этого?

var = something.very.long.and.tedious.to.write || something.other
...