Lubię jak w Ruby można przekazać metod jako bloki podobnie jak przy użyciu Symbol#to_proc
:Symbol # to_proc metodami niestandardowymi
[1.0, 2.0, 3.0].map(&:to_i)
#=> [1, 2, 3]
Mogę również definiować własne lambda times_two
i przekazać go jako blok, a także :
times_two = ->(x) {x * 2}
[1, 2, 3].map(×_two)
#=> [2, 4, 6]
Choć pozornie nie może wprost times_two
jako symbol:
[1, 2, 3].map(&:times_two)
#=> ArgumentError: wrong number of arguments (0 for 1)
Jednak gdy próbuję zrobić to samo z metody pojawia się błąd:
def times_three(x)
x * 3
end
[1, 2, 3].map(×_three)
#=> ArgumentError: wrong number of arguments (0 for 1)
[1, 2, 3].map(&:times_three)
#=> ArgumentError: wrong number of arguments (0 for 1)
Zgaduję, że nie może tego zrobić, ponieważ times_three
jest metodą, a nie Proc.
Jak zdefiniować metody niestandardowe, aby można je było stosować w stylu w pierwszym przykładzie powyżej?
Na przykład, jak mogę to zrobić?
[1, 2, 3].map(&:times_three)
#=> [3, 6, 9]
EDIT: oglądałem film pisał poniżej i widocznie można zbliżyć się do Symbol # to_proc stosując metodę method
:
def times_three(x)
x * 3
end
t_three = method(:times_three)
[1, 2, 3].map(&t_three)
#=> [3, 6, 9]
Jednak nie dość Symbol # to_proc:
[1, 2, 3].map(&:t_three)
#=> NoMethodError: undefined method `t_three' for 1:FixNum
Bardzo dziękuję za to jasne wyjaśnienie, Steve. Skoro już wiem, jak to zrobić, czy dopuszczalne jest praktykowanie małpich klas rdzeniowych za pomocą takich metod, aby wyczyścić skomplikowane lub powtarzające się bloki? – garythegoat
Cóż, tak, pod warunkiem, że intencja jest jasna i jest pewna korzyść, na pewno jest łatka dla małpy. W tym tygodniu miałem aplikację szyn, w której obowiązkowe pola wejściowe miały gwiazdkę w etykietach, np. '' First Name * '' and ''City *'' i firma nagle chciała, aby wszystkie gwiazdki miały czerwony kolor czcionki. Mógłbym napisać metodę pomocniczą, taką jak 'red_asterisk ('First Name *')' ale łatwiej było małpować łatkę klasy String ''First Name *." Red_asterisk', a następnie po prostu zrobić globalne find/replace on '* "więc stało się' * '. red_asterisk' – SteveTurczyn
Steve, jak dobrze wiesz, 'return' nie jest potrzebny. 'self' jest jednak. Zakładam, że 'self' musi być jawne dla takich metod, jak' * ','% ', które są fakturowane za pomocą cukru syntaktycznego. Czy ty lub ktoś inny wie, czy to prawda? –