##WITHOUT #SEND
#This solution only works as long as you know exactly what methods are going to be called. What if you didn't? What if you did not know all the actions that were possible on the glider object? If only there was a generic way
class Glider
def lift
puts "Rising"
end
def bank
puts "Turning"
end
end
class Nomad
def initialize(glider)
@glider = glider
end
def do(action)
if action == 'lift'
@glider.lift
elsif action == 'bank'
@glider.bank
else
raise NoMethodError.new(action)
end
end
end
nomad = Nomad.new(Glider.new)
nomad.do("lift")
nomad.do("bank")
### WITH #SEND
#Ruby gives a convenient way for you to call any method on an object by using the send method. send takes, as its first argument, the name of the method that you want to call. This name can either be a symbol or a string.
class Nomad
def initialize(glider)
@glider = glider
end
def do(action)
@glider.send(action)
end
end
#Additionally, now some of these actions require further arguments. e.g. The command to 'bank' takes a string of either 'left' or 'right', while the command to 'roll' takes the number of degrees it should dive for. Again, send gives us a convenient way to pass arguments to these methods. All further arguments to send after the first (which you'll recall has the name of the method you want called itself) become arguments that get passed down to that method.
class Nomad
def initialize(glider)
@glider = glider
end
def do(action, argument = nil)
if argument == nil
@glider.send(action)
else
@glider.send(action, argument)
end
end
end
#### WITHOUT #SEND
class Sorter
def move_higher
puts "moved one higher"
end
def move_lower
puts "moved one lower"
end
def move(type)
case type
when "higher" then move_higher
when "lower" then move_lower
end
end
end
##### WITH #SEND
class Sorter
def move_higher
puts "moved one higher"
end
def move_lower
puts "moved one lower"
end
def move(type)
self.send "move_" + type
end
end