4

I have a string that I want to use as part of a variable name. Specifically, in Rails route paths:

<%= foo_path %>
<%= bar_path %>

I want the first part of the route name to be dynamic. So something like

@lol = "foo"
<%= [@lol]_path %> # <-- This would really be the "foo_path" variable

Can Ruby do this?

Jordan Running
  • 102,619
  • 17
  • 182
  • 182
Tim
  • 6,079
  • 8
  • 35
  • 41

2 Answers2

10

Sure:

lol = 'foo'

send "#{lol}_path"
# or
send lol + '_path'

Explanation: Object#send sends the method to (i.e. "calls" the method on) the receiver. As with any method call, without an explicit receiver (e.g. some_object.send 'foo') the current context becomes the receiver, so calling send :foo is equivalent to self.send :foo. In fact Rails uses this technique behind the scenes quite a lot (e.g.).

Jordan Running
  • 102,619
  • 17
  • 182
  • 182
  • 3
    epic!! for purpose of pedagogy, how would someone learn something like this? Just from longer exposure to Ruby? – Tim Nov 16 '11 at 06:16
  • 2
    Exposure will help, certainly, but if you're going to use Ruby you could do much worse than to read through the docs for as many of the core classes as you can, in particular [Object](http://www.ruby-doc.org/core-1.9.3/Object.html) and [Kernel](http://www.ruby-doc.org/core-1.9.3/Kernel.html) (but really [none of them](http://www.ruby-doc.org/core-1.9.3/) is very long). And don't forget [the Pickaxe](http://www.rubycentral.com/pickaxe/), the seminal (and free) Ruby book. – Jordan Running Nov 16 '11 at 06:22
  • I read those source, and I don't get them. It helps so much more when someone explains, teaches, or shows me. Or at least gets me to the point of being able to understand. There are technical glass ceilings when starting out that become invisible to seasoned programmers. – ahnbizcad Jun 29 '14 at 08:43
  • The Pickaxe link in my previous comment is broken. Here's a working link: http://ruby-doc.com/docs/ProgrammingRuby/ – Jordan Running Jun 30 '14 at 15:26
2

Something more!

class Person
  attr_accessor :pet
end

class Pet
  def make_noise
     "Woof! Woof!"
  end
end

var_name = "pet"
p = Person.new
p.pet = Pet.new
(p.send "#{var_name}").make_noise

So what's happening here is:
p.send "some_method" calls p.some_method and the parenthesis surrounding makes the chaining possible i.e. call p.pet.make_noise in the end. Hope I'm clear.

oozzal
  • 2,441
  • 23
  • 21