uczę Ruby (2.0) i to właśnie mnie zaskoczyła:
s = "1234"
s =~ /\d+/
$& ==> "1234" # as expected, $& contains the matched string
$&.slice!(-2..-1) # should mutate string
$& ==> "1234" # what?
s.slice(-2..-1)
s ==> "12" # as expected
Sposób slice!
ma zmutować ciąg. Inne metody mutatora zachowują się w ten sam sposób. Moje pytania: dlaczego nie powoduje to błędu, czego oczekuję, gdy funkcja nie może zrobić tego, co mówi? Czy to gdzieś dokumentuje? Czy istnieje uzasadnienie?
Aktualizacja
Tak, widzę, że $&
nie zachowuje się jak zmiennej globalnej. Każde odniesienie do niej daje nowy obiekt, jakby to naprawdę funkcja no-arg:
irb> $foo = "1234"
=> "1234"
irb> $foo.object_id
=> 70205012205980
irb> $foo.object_id
=> 70205012205980 # the same
irb> $&.object_id
=> 70205003531300
irb> $&.object_id
=> 70205011619040 # different object
... Więc moje pytanie brzmi: czy jest to po prostu „magię” od tłumacza, czy rzeczywiście nie $&
Funkcja -arg tak, jak mógłbym zdefiniować w Rubim używając def ... end
? I jak mogę odróżnić? W Pythonie mogę odnosić się do funkcji foo
używając tylko jego nazwa:
>>> foo
<function foo at 0x10d3117d0>
Czy istnieje sposób, aby zrobić to w Ruby? Mógłbym wtedy spojrzeć na to, czym jest "naprawdę" & (jeśli to nie jest magia).
Dlaczego chcesz zmienić '$ &'? Okłamać kolejny kod o tym, co zostało dopasowane? Zauważ, że '$ &' nie ma żadnych "setterów": '$ &. Methods.grep (/ = /) => [: ===,: = ~,: <=>,: ==,:! = ] ' –
Parsuję coś, a metoda' slice! 'Zapewniła wygodny sposób na wybranie napisu, tak jak chciałem, w jednym wierszu. Ale to nie ma znaczenia. Obiekt ma typ String, dlatego powinien odpowiadać na metody String. Ma mutatory (metody, które kończą się!), A jeśli obiekt nie może odpowiedzieć na jego metodę, powinien rzucić wyjątek. –
"Obiekt ma typ String". Obiekt * zwrócony * jest ciągiem. Przypisuj to do czegoś i możesz je połączyć z treścią twojego serca. Zmiana '$ &' byłaby zła. Zmiana tego, co zwraca '$ i', jest w porządku. –