/ / Jak działa instrukcja „case” ze stałymi? - ruby, class, constants, switch-statement

W jaki sposób instrukcja "case" działa ze stałymi? - ruby, klasa, stałe, switch-statement

Używam Ruby 1.9.2 i Ruby on Rails 3.2.2. Mam następującą metodę:

# 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

Chciałbym zrozumieć, dlaczego w case powyżej, zawsze uruchamia else „część”, gdy wykonuję wywołania metod, takie jak my_method(Article), my_method(Comment) i tak dalej.

Jak mogę rozwiązać ten problem? Czy ktoś ma radę, jak sobie z tym poradzić?

Odpowiedzi:

4 dla odpowiedzi № 1

To dlatego, że case połączenia ===, i === w klasie (a konkretnie moduł, z którego wywodzi się klasa) jest zaimplementowany w następujący sposób:

mod === objtrue lub false

Równość wielkości liter - zwroty true gdyby obj jest instancją mod lub jeden z modPotomkowie. Ma ograniczone zastosowanie dla modułów, ale może być używany w instrukcjach case do klasyfikowania obiektów według klas.

Oznacza to, że dla każdej stałej z wyjątkiem Class & Module (na przykład. Foo), Foo === Foo zawsze wraca false. W rezultacie zawsze otrzymujesz else stan w twoim case komunikat.

Zamiast tego po prostu zadzwoń case z samym obiektem zamiast jego klasy lub use if sprawozdania.


3 dla odpowiedzi № 2

Przekaż odwołanie do obiektu do metody, ponieważ w tle używa ona operatora ===, więc to się nie powiedzie. na przykład

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 z drugiej strony działa dobrze:

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

Zobacz odpowiednią odpowiedź na temat „Jak napisać instrukcję przełącznika w języku Ruby” https://stackoverflow.com/a/5694333/1092644


1 dla odpowiedzi nr 3

Możesz dodać to_s do stałej klasy, jeśli chcesz tylko porównać równość nazw.

def my_method(class_name)
case class_name.to_s
when "Article"
make_a_thing
when "Comment"
make_another_thing

... ...

end
end