Ways to call a method in Ruby

#code #summary #method #calls #ruby

class Client def send(message) = puts message end class TweetService def initialize(client) = @client = client def post(message) = @client.send(message) def hello_world=@client.send("Hello world 8!") def method_missing(name,...) = post(tweet_from_method_name(name.to_s)) private def tweet_from_method_name(name) = sentence(name.gsub(/exclamation_mark/,'!').split("_")) def sentence(words) = words.map(&:capitalize).join(" ") def private_post(message) = @client.send(message) end service=TweetService.new(Client.new)
# Part 2️⃣/4: Ways to call a method # The obvious way service.post("Hello World 1!") service.post "Hello World 2!" # Using send and public_send service.send(:private_post, "Hello World 3!") # works on private too service.public_send(:post, "Hello World 4!") # Using "method" and "call" service.method(:post).call("Hello world 5!") service.method(:post).("Hello world 6!") # Using "tap" service.tap { _1.post("Hello world 7!") } service.tap(&:hello_world) # Using "to_proc" on function name :post.to_proc.call(service, "Hello world 9!") # Using method missing service.hello_world_10_exclamation_mark service.yes_exclamation_mark_it_works_dont_do_it_in_production # Using eval eval("service.post('Hello World 11!')")
# Part 3️⃣/4: Other ways to call a method # with __send__ service.__send__(:post, "Extra #1!") # Using [] shorthand syntax for call service.method(:post)["Extra #2!"] # With lambda service.tap(&->(object) { object.post("Extra #3!")}) # or post_lambda=->(service) { service.post("Extra #4!")} service.tap(&post_lambda) # With proc service.tap(&(Proc.new { _1.post("Extra #5!")})) # or post_proc=Proc.new { _1.post("Extra #6!")} service.tap(&post_proc) # It works with `then` too if you want to get the result also # `tap` will discard the result result=service.then { _1.post("Extra #7!") }
# Part 4️⃣/4: using bind and binding method=TweetService.instance_method(:post) method.bind(service).call("Extra #8!") # with bind, you can change the context where this executes class ClientOauthV2 def send(message) = puts "[OauthV2] #{message}" end class TweetServiceV2 < TweetService def initialize(client = ClientOauthV2.new) = super end new_service=TweetServiceV2.new method.bind(new_service).call("Extra #9!") # You can also get binding and then eval in that context class TweetServiceV2 < TweetService def get_binding=binding end context=new_service.get_binding context.eval("post('Extra #10!')") # or eval("post('Extra #11!')", context)

The source code if you want to play with this is here.

Reply

or to participate.