Nie wiem, dlaczego wszyscy sugerują, że powinieneś używać instance_methods
i include?
kiedy method_defined?
wykonuje swoją pracę.
class Test
def hello; end
end
Test.method_defined? :hello #=> true
UWAGA
Jeśli przyjeżdżasz do Ruby z innego języka OO LUB uważasz, że method_defined
oznacza to TYLKO metody, które wyraźnie zdefiniowałeś za pomocą:
def my_method
end
następnie przeczytaj to:
W Ruby właściwość (atrybut) w twoim modelu jest w zasadzie również metodą. Zwróci method_defined?
również wartość true dla właściwości, a nie tylko metod.
Na przykład:
Biorąc pod uwagę instancję klasy, która ma atrybut String first_name
:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
ponieważ first_name
jest zarówno atrybutem, jak i metodą (oraz łańcuchem typu String).
String.instance_methods(false).include? :freeze
, fałszywy argument może dokładnie powiedzieć, czyfreeze
metoda jest zdefiniowana w klasie String, czy nie. W takim przypadku zwróci false, ponieważfreeze
metoda jest dziedziczona z modułu jądra przez String, aleString.method_defined? :freeze
zawsze zwróci true, co niewiele może pomóc w takim celu.method_defined?
musi być użyty w klasie (np.Array
), ale próbujesz użyć go w instancjach (np.[]
)Możesz użyć
method_defined?
w następujący sposób:Znacznie łatwiejsze, przenośniejsze i wydajniejsze niż
instance_methods.include?
sugerują to wszyscy inni.Pamiętaj, że nie będziesz wiedział, czy klasa reaguje dynamicznie na niektóre wywołania
method_missing
, na przykład poprzez redefiniowanierespond_to?
lub od Ruby 1.9.2 poprzez zdefiniowanierespond_to_missing?
.źródło
instance.class.method_defined? :upcase
W rzeczywistości nie działa to zarówno dla obiektów, jak i klas.
To robi:
Tak więc przy podanej odpowiedzi działa to:
Ale to NIE działa:
Używam tego zarówno dla klas, jak i obiektów:
Klasy:
Obiekty:
źródło
Odpowiedź na „ Biorąc pod uwagę klasę, czy instancja ma metodę (Ruby) ” jest lepsza. Najwyraźniej Ruby ma to wbudowane i jakoś mi tego brakowało. Moja odpowiedź pozostawia się do odniesienia, niezależnie od tego.
Klasy Ruby odpowiadają na metody
instance_methods
ipublic_instance_methods
. W Ruby 1.8 pierwszy wyświetla wszystkie nazwy metod instancji w tablicy ciągów, a drugi ogranicza je do metod publicznych. Drugie zachowanie jest najbardziej pożądane, ponieważrespond_to?
domyślnie ogranicza się również do metod publicznych.Jednak w Ruby 1.9 metody te zwracają tablice symboli.
Jeśli planujesz to robić często, możesz chcieć rozszerzyć
Module
o metodę skrótów. (Może się to wydawać dziwne, aby przypisać toModule
zamiastClass
, ale ponieważ tam właśnieinstance_methods
żyją metody, najlepiej trzymać się tego wzorca.)Jeśli chcesz obsługiwać zarówno Ruby 1.8, jak i Ruby 1.9, byłoby to wygodne miejsce na dodanie logiki do wyszukiwania zarówno ciągów znaków, jak i symboli.
źródło
method_defined?
jest lepiej :)Próbować
Foo.instance_methods.include? :bar
źródło
Nie jestem pewien, czy to najlepszy sposób, ale zawsze możesz to zrobić:
źródło
Myślę, że coś jest nie tak z
method_defined?
Railsami. Może to być niespójne lub coś, więc jeśli używasz Railsów, lepiej użyć czegoś zattribute_method?(attribute)
.„ testowanie metody method_defined? w klasach ActiveRecord nie działa aż do wystąpienia wystąpienia ” to pytanie o niespójność.
źródło
Jeśli sprawdzasz, czy obiekt może odpowiedzieć na szereg metod, możesz zrobić coś takiego:
methods & something.methods
dołączy do dwóch tablic na ich elementów wspólnych / dopasowanie. coś.metody obejmują wszystkie sprawdzane metody, będą równe metodom. Na przykład:więc
W tej sytuacji chciałbyś użyć symboli, ponieważ gdy wywołasz .methods, zwróci tablicę symboli, a jeśli użyjesz
["my", "methods"]
, zwróci false.źródło
klass.instance_methods.include :method_name
lub"method_name"
, w zależności od wersji Ruby, myślę.źródło
Mam nadzieję, że to ci pomoże!
źródło
W moim przypadku praca z Ruby 2.5.3 działały idealnie następujące zdania:
Zwróci wartość logiczną true lub false.
źródło
Chociaż
respond_to?
zwróci prawdę tylko w przypadku metod publicznych, sprawdzanie „definicji metody” w klasie może również dotyczyć metod prywatnych.W Ruby v2.0 + można sprawdzać zarówno zestawy publiczne, jak i prywatne
źródło