if ( item::class == RPG::Weapon )
print "yup"
end
case item::class
when RPG::Item
type = 0
when RPG::Weapon
type = 1
when RPG::Armor
type = 2
else
type = 10
end
I'm new to Ruby. The if statement runs fine and prints "yup", but the case statement isn't working properly and sets type to 10. Am I blind to something or what?
Module#===
tests if the argument is an instance of self
. item.class
can never be an instance of anything but Class
, in particular, it will never be an instance of either RPG::Weapon
or RPG::Armor
, therefore none of the when
branches will ever match and you will always get the else
branch.
By the way: using the namespace resolution operator ::
for message sends instead of the message sending operator .
is extremely un-idiomatic and confusing (and won't work for methods whose name starts with an uppercase character). In fact, I believe matz considers adding this feature to Ruby a mistake.
Note also that case
is an expression, in fact, everything in Ruby is an expression.
I would write the code as follows:
type = case item
when RPG::Item
0
when RPG::Weapon
1
when RPG::Armor
2
else
10
end
However, in general, conditionals are a code smell. Ruby is an object-oriented language, polymorphism (ie method dispatching based on the type of self
) is all the conditional you need ! In fact, in this very example, you are manually examining the class of item
in order to determine its type, but that is exactly what method dispatch does anyway! Personally, I would refactor this code like this:
class RPG::Item
def type
0
end
end
class RPG::Weapon
def type
1
end
end
class RPG::Armor
def type
2
end
end
class RPG::Object # or whatever your baseclass is
def type
10
end
end
Now when you add a new kind of game object, you don't have to modify your existing code by adding a new branch to your case
expression. You just add the new class, without needing to modify any existing code.
Just case item
will be sufficient - no need for case item::class
.
Case matching in Ruby is done with a fuzzy matching ( ===
) algorithm that doesn't need such specific clauses.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.