Parser rubinowy ma specjalny przypadek do wyrażenia regularnego literałów w wersjach warunkowych. Zwykle (tj.bez korzystania z opcji wiersza poleceń e
, n
lub p
) ten kod:
if /foo/
puts "TRUE!"
end
produkuje:
$ ruby regex-in-conditional1.rb
regex-in-conditional1.rb:1: warning: regex literal in condition
Przypisywanie coś, co pasuje do wyrażenia regularnego do $_
pierwszy coś takiego:
$_ = 'foo'
if /foo/
puts "TRUE!"
end
produkuje:
$ ruby regex-in-conditional2.rb
regex-in-conditional2.rb:2: warning: regex literal in condition
TRUE!
Jest to (źle udokumentowany) wyjątek od normalnych reguł dla warunków Ruby, gdzie wszystko, co nie jest zgodne z false
lub nil
, jest traktowane jako prawda.
Dotyczy to tylko regex literałów, następujące zachowuje się jak można się spodziewać na warunkowy:
regex = /foo/
if regex
puts "TRUE!"
end
wyjściowa:
$ ruby regex-in-conditional3.rb
TRUE!
To jest obsługiwane przez parser. Przeszukiwanie kod MRI dla tekstu ostrzeżenia produkuje jeden match in parse.y
:
case NODE_DREGX:
case NODE_DREGX_ONCE:
warning_unless_e_option(parser, node, "regex literal in condition");
return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
Nie wiem, bizony, więc nie mogę dokładnie wyjaśnić, co tu się dzieje, ale istnieją pewne wskazówki można wydedukować . Funkcja warning_unless_e_option
po prostu blokuje ostrzeżenie, jeśli została ustawiona opcja -e
, ponieważ ta funkcja jest odradzana w normalnym kodzie, ale może być przydatna w wyrażeniach z wiersza poleceń (to wyjaśnia, dlaczego nie widzisz ostrzeżenia w kodzie). Następna linia wydaje się konstruować poddrzewo parse, które jest dopasowaniem wyrażenia regularnego między zmienną globalną regex a $_
, która zawiera "[t]he last input line of string by gets or readline". Węzły te zostaną następnie skompilowane do wywołania metody zwykłego wyrażenia regularnego.
To pokazuje, co się dzieje, po prostu zakończyć cytatem z Kernel#gets
documentation które mogą wyjaśnić, dlaczego to jest tak niejasny funkcji może
Styl programowania przy użyciu $ _ jako niejawna parametr jest stopniowo tracąc przysługę w społeczności Ruby.
jeśli/hello/jest truthy jest wszystko, co jest, to nie jest fałszywy i nie zerowe –
@TonyHopkinson to nieprawda, można zmodyfikować regex pasujące do niczego - spowoduje żadnych ouput – Shawn
Czy jak Perl gdzie kiedy użyto '-n'' $ _' staje się niejawnym argumentem? A może '$ _' jest niejawne w wyrażeniu regularnym przez cały czas. –