Reputation: 2566
Ruby toddler here (3 days playing with Ruby, probably my terminology is yet imprecise).
For study reason I would like to modify the following code to accept ticket.request("triple",10)
(or equivalent syntax) in the second last line.
Is it possible (without heavily changing ticket.request
)?
ticket = Object.new
def ticket.price
return 3.5
end
def ticket.triple(c)
return 3*c
end
# direct call
puts ticket.triple(10) # ===> 30
# pointer to method
pt = ticket.method(:triple)
puts pt.call(10) # ===> 30
def ticket.request(request) # <=== should it be modified?
if self.respond_to?(request)
self.__send__(request)
end # nil otherwise
end
puts [
ticket.price, # direct ===> 3.5
ticket.request("price"), # safe ===> 3.5
ticket.request("name") # it does not exist ===> nil
# ticket.request("triple", 10) <========================= syntax ????
]
Upvotes: 0
Views: 104
Reputation: 51151
So, basically you need ticket.request
method to take also arguments you want to be passed to subsequent method call? It is possible, if so:
def ticket.request(request, *args)
if respond_to?(request)
send(request, *args)
end
end
puts [
ticket.price, # direct ===> 3.5
ticket.request("price"), # safe ===> 3.5
ticket.request("name") # it does not exist ===> nil
ticket.request("triple", 10)
]
*args
in method definition works as "take the rest of arguments and store them in args
array. In the method call it works in quite opposite way - as "take args
array and make it an argument list passed into the method".
Note that I deleted redundant self
keywords, as self
is default receiver of the message. I also used send
method, as it's used more commonly.
Upvotes: 1
Reputation: 106802
I would do something like this:
def ticket.request(request, *args)
if self.respond_to?(request)
self.__send__(request, *args)
end
end
Upvotes: 1