Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: interpolated string to variable name [duplicate]

In Ruby, how can I interpolate a string to make a variable name?

I want to be able to set a variable like so:

"post_#{id}" = true

This returns a syntax error, funnily enough:

syntax error, unexpected '=', expecting keyword_end
like image 883
t56k Avatar asked May 22 '17 15:05

t56k


People also ask

How do you interpolate a string in Ruby?

Eventually, the objects(1, 2) created in this process gets terminated as they are of no use. In String Interpolation, it creates an only one object for (“hela “+string+” puri”) and embeds the existing string(weds)to it. In both the case, in the end, it creates one object but why prefer Interpolation over concatenation.

What's the difference between concatenation and interpolation Ruby?

Concatenation allows you to combine to strings together and it only works on two strings. Swift uses string interpolation to include the name of a constant or variable as a placeholder in a longer string, and to prompt Swift to replace it with the current value of that constant or variable.

What is %{} in ruby?

This is percent sign notation. The percent sign indicates that the next character is a literal delimiter, and you can use any (non alphanumeric) one you want. For example: %{stuff} %[stuff] %?


1 Answers

I believe you can do something like:

  send("post_#{id}=", true)

That would require, of course, that you have appropriate setter/getter. Which, since you're doing this dynamically, you probably don't.

So, perhaps you could do:

  instance_variable_set("@post_#{id}",true)

To retrieve the variable:

  instance_variable_get("@post_#{id}")

BTW, if you get tired of typing instance_variable_set("@post_#{id}",true), just for fun you could do something like:

class Foo

  def dynamic_accessor(name) 
    class_eval do 
      define_method "#{name}" do
        instance_variable_get("@#{name}")
      end
      define_method "#{name}=" do |val|
        instance_variable_set("@#{name}",val)
      end
    end
  end

end

In which case you could:

2.3.1 :017 > id = 2
 => 2 
2.3.1 :018 > f = Foo.new
 => #<Foo:0x00000005436f20> 
2.3.1 :019 > f.dynamic_accessor("post_#{id}")
 => :post_2= 
2.3.1 :020 > f.send("post_#{id}=", true)
 => true 
2.3.1 :021 > f.send("post_#{id}")
 => true 
2.3.1 :022 > f.send("post_#{id}=", "bar")
 => "bar" 
2.3.1 :023 > f.send("post_#{id}")
 => "bar" 
like image 120
jvillian Avatar answered Nov 15 '22 00:11

jvillian