I've done a lot of searching about casting an object in Ruby, and can only find examples of casting a string to an integer or vice versa. I'm curious how to cast other, more complex objects..
For Example with these classes...
class Animal
attr_accessor :weight, :name
end
class Duck < Animal
def speak
'Quack'
end
end
I would expect to be able to do something like the following.
irb> animal = Animal.new
irb> duck = (Duck)animal
irb> duck.speak
=> "Quack"
But I can't quite figure out how to do the casting as I would expect in Java or a similar language.
An object in Ruby is created with a particular class and it will be destroyed with the same class, it never changes. You can't cast, either, all you can do is call functions which convert, a process that involves creating a new object or using another as a proxy.
In your case you can't cast, but you can create a duck with identical properties:
class Animal
attr_accessor :weight, :name
def initialize(options)
# Allow calling new with either an options hash, or another
# animal that's intended to be cloned.
case (options)
when Animal
@weight = options.weight
@name = options.name
when Hash
@weight = options[:weight]
@name = options[:name]
end
end
end
class Duck < Animal
def speak(phrase)
'%s says %s' % [ name, phrase.inspect ]
end
end
animal = Animal.new(weight: 10, name: 'Bill')
duck = Duck.new(animal)
puts duck.speak('quack!')
A second option is to move the duck-like functionality to a separate module you can mix-in:
module ActsAsDuck
def speak
'Quack!'
end
end
animal.extend(ActsAsDuck)
puts animal.speak
That mixes in any methods in that module into your object instance.
One thing that you should understand about Ruby is that the concept of type is not related to the class of an object. An object can respond to multiple interfaces other than it's original class (for example, by including modules or defining singleton methods). So, it's not necessary to typecast an object to have access to a particular interface. This means that is not important what an object is, the really important thing its what it's does.
This concept applies to strings and integers too. You don't typecast a string to integer, you ask a string object to create a new integer that is its idea of itself in this form.
If you want a further understanding about this, I suggest you to read about a concept known as Duck typing
In your case you can just instantiate a Duck object directly like this:
irb> duck = Duck.new
irb> duck.quack
=> "Quack"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With