Používam Ruby 1.9.2 a Ruby on Rails 3.2.2. Mám nasledujúcu metódu:
# Note: The "class_name" parameter is a constant; that is, it is a model class name.
def my_method(class_name)
case class_name
when Article then make_a_thing
when Comment then make_another_thing
when ... then ...
else raise("Wrong #{class_name}!")
end
end
Chcel by som pochopiť, prečo v case
vyššie, vždy sa spustí príkaz else
"časť", keď vykonávam volania metód ako my_method(Article)
, my_method(Comment)
a tak ďalej.
Ako môžem vyriešiť problém? Má niekto radu, ako to má vyriešiť?
odpovede:
4 pre odpoveď č. 1To je preto, že case
volá ===
, a ===
na Triede (alebo konkrétne Modul, z ktorého trieda pochádza) je implementovaný takto:
mod === obj
→true
alebofalse
Rovnosť prípadov - vracia sa
true
akobj
je príkladommod
alebo jeden z nichmod
Potomkovia. Má obmedzené použitie pre moduly, ale dá sa použiť v príkazoch case na klasifikáciu objektov podľa triedy.
To znamená, že pre každú konštantu okrem Class
& Module
(Napr. Foo
) Foo === Foo
vždy sa vracia false
. Vďaka tomu vždy získate else
stav vo vašom case
vyhlásenia.
Namiesto toho len zavolajte case
so samotným objektom, namiesto jeho triedy, alebo použiť if
príkazy.
3 pre odpoveď č. 2
Odošlite odkaz na objekt k metóde, pretože na pozadí používa operátor ===, takže tieto zlyhajú. napr.
obj = "hello"
case obj.class
when String
print("It is a string")
when Fixnum
print("It is a number")
else
print("It is not a string")
end
To na druhej strane funguje dobre:
obj = "hello"
case obj # was case obj.class
when String
print("It is a string")
when Fixnum
print("It is a number")
else
print("It is not a string")
end
Pozrite si príslušnú odpoveď na otázku „Ako napísať príkaz switch v Ruby“ https://stackoverflow.com/a/5694333/1092644
1 pre odpoveď č. 3
Môžete pridať to_s
na konštantu triedy, ak chcete iba porovnať rovnosť mien.
def my_method(class_name)
case class_name.to_s
when "Article"
make_a_thing
when "Comment"
make_another_thing
... ...
end
end