Jaki jest właściwy sposób robienia tego w Ruby?Idiomy Rubiego: wywołanie metody lub domyślnie
def callOrElse(obj, method, default)
if obj.respond_to?(method)
obj.__send__(method)
else
default
end
end
Jaki jest właściwy sposób robienia tego w Ruby?Idiomy Rubiego: wywołanie metody lub domyślnie
def callOrElse(obj, method, default)
if obj.respond_to?(method)
obj.__send__(method)
else
default
end
end
Ponieważ nie zostały zaproponowane jako odpowiedź:
result = obj.method rescue default
As z @slhck, pewnie nie byłoby to wykorzystać, kiedy wiedział, że rozsądna szansa, że obiekt nie zareaguje na metodę, ale jest to opcja.
To proste, ma to poważną wadę polegającą na zasłanianiu wszelkich wyjątków, które objmethod podnosi, nie będziesz wiedział, czy nie ma metody, czy nie. Osobiście uniknęłabym miejscowych rat, gdy tylko było to możliwe. – tokland
-1 Z tego powodu wspomniano o @tokland. Naprawdę nie możesz użyć tego jako ogólnej strategii. – Jazzepi
pewnie bym iść do
obj.respond_to?(method) ? obj.__send__(method) : default
Jest to znacznie czystsze, ale ma zasadniczo tę samą funkcjonalność. Myślałem, że będzie lepszy sposób na zrobienie tego. – dsg
Cóż, czego chcesz, jeśli nie to samo _funkcjonalność_? :) Jeśli chodzi o mnie, nie ma sposobu, aby ominąć tę decyzję. Ale może ktoś ma pomysł. – slhck
Miałem nadzieję na coś takiego: 'x = obj.method || default'. – dsg
więc chcesz coś podobnego do x = obj.method || default
? Ruby to idealny język do budowania własnych konstrukcji bottom-up:
class Object
def try_method(name, *args, &block)
self.respond_to?(name) ? self.send(name, *args, &block) : nil
end
end
p "Hello".try_method(:downcase) || "default" # "hello"
p "hello".try_method(:not_existing) || "default" # "default"
Może nie lubisz tego pośredniego dzwonienia za pomocą symboli? Nie ma problemu, a następnie spójrz na Ick „s maybe
stylu i użyć obiektu proxy (można dowiedzieć się realizacji): notatka
p "hello".maybe_has_method.not_existing || "default" # "default"
niepożądane: Nie jestem ekspertem OOP, ale to jest moje zrozumienie, że trzeba wiedzieć, czy obiekt, do którego dzwonisz, ma taką metodę wcześniej. Czy jest to obiekt, który chcesz kontrolować, aby nie wysyłać metod? Im ten przypadek Ick jest już miły rozwiązanie: object_or_nil.maybe.method || default
Jest to na ogół dobra odpowiedź, ale należy pamiętać, że implementacja spowoduje, że istniejąca metoda zwróci wartość "false" lub "nil" zamiast "domyślnej". – Phrogz
@Phrogz: To dobrze, ale jest mało prawdopodobne, że potrzebujesz wartości domyślnej w tym przypadku, po prostu napisz warunek "if obj.maybe.enabled?". W każdym razie, zawsze możesz dostosować wzór do swoich potrzeb: "obj.maybe (: default => true) .active?", Ale "|| default" powinien obejmować typowe przypadki. – tokland
Czy EAFP (tj. Użyj spróbuj - z wyjątkiem tutaj) nie jest objęty społecznością Ruby tak jak jest to napisane przez Pythonistas? –
@Karl. Nie mówię o wszystkich Rubyistach, ale pisanie (przynajmniej) czterech linii o coś, co można zrobić w jednym, jest zdecydowanie irytujące dla wielu programistów Ruby (coś, co prawdopodobnie nie miałoby nic przeciwko Pythonowi). – tokland
Co więcej, nie użyłbym konstrukcji try/except tutaj, jeśli to, co zamierza OP, zawiera zachowanie __default__. Moim zdaniem, jeśli oba sposoby (np. "Wyślij" i "domyślny") mogą wystąpić, dlaczego sprawiają, że jest to "wyjątek"? – slhck