0

Suppose we want social_link(user, social) to return the user's social media link, how can we define that function so that the 'social' argument is used as a method on the user argument?

i.e.

if social_link(user, "facebook"), then it would run

user.facebook

or if social_link(user, "twitch"), then:

user.twitch

and so on, with the key idea being that the function should take the string argument and call that string as a method on another object.

i.e something like

def social_link(user, social) 
  user.<social>
end

What is the syntax required to make this kind of function work?

stevec
  • 41,291
  • 27
  • 223
  • 311

1 Answers1

0

Edit: As @stefan has pointed out the syntax you're probably looking for is:

user.public_send(social)

I think I saw the word "define" and jumped to this response below. The original response shouldn't be used carelessly.

Original:

Yes, ruby has the syntax you're looking for with define_method and method_missing:

class User
  def method_missing(m, *args, &block)
    self.class.send(:define_method, m) do |args|
      puts args
    end
    send(m, args)
  end

  def facebook(args)
    puts args
    puts "do the fb thing"
  end
end

u = User.new
u.instagram("does the instagram thing")
u.twitch("does the twitch thing")

In ruby "everything is an object." So when we use the instance.method syntax, what's really going on is we're sending instance the "message" method where the . (dot operator) is essentially the "send" operator.

method_missing is the method/function that receives "unknown messages." Here, we're intercepting the "message," in this case "instagram," defining it on the fly then sending the *args to that method m.

eric
  • 1,029
  • 1
  • 8
  • 9
  • 1
    Just googling those terms. Look forward to the example. Upvoted – stevec Dec 02 '20 at 04:17
  • some other keywords that you might find helpful in the process are `responds_to?`, `alias`, and `instance_variable_set`, there are others but these will lead you to those ha – eric Dec 02 '20 at 04:56
  • 3
    The question is about _calling_ existing methods dynamically, not about creating new ones. – Stefan Dec 02 '20 at 05:11