0

I have a Ruby project where I programmatically get the names of keys in a hash I need to access. I can access the fields I need in the following way:

current_content = entry.fields[property_name.to_sym]

However, it seems that some content can only be accessed with a property syntax:

m.title_with_locales = {'en-US' => 'US Title', 'nl' => 'NL Title'}

Since I don't know "title" ahead of time, how can I make a call programmatically? Ex:

m.${property_name}_with_locales = {'en-US' => 'US Title', 'nl' => 'NL Title'}
skaz
  • 21,216
  • 19
  • 67
  • 95

2 Answers2

4

You can use #send to programmatically access properties:

m.send("#{property_name}_with_locales")
# => { 'en-US' => 'US Title', ... }

If you need to access a setter and pass in values, you can do:

m.send("#{property_name}_with_locales=", { 'whatever' => 'value' })
gwcodes
  • 5,512
  • 1
  • 10
  • 19
0

beside send as @gwcodes had written, there are also, eval and call.

2.3.1 :010 > a
 => [1, 2, 3] 
2.3.1 :011 > a.send("length")
 => 3 
2.3.1 :012 > a.method("length").call
 => 3 
2.3.1 :013 > eval "a.length"
 => 3 

as shown on this blog post call is a bit faster than send.

marmeladze
  • 6,048
  • 3
  • 24
  • 42
  • 1
    beware old benchmarks - from 2008! :-) This isn't true in more recent versions of Ruby, and `send` should actually be faster (but we're talking minuscule differences here) – gwcodes Apr 04 '17 at 12:43
  • sorry, i've not updated myself -)) – marmeladze Apr 04 '17 at 13:04
  • Never use `eval` unless you absolutely positively have to and understand the consequences of doing so (i.e. the danger of introducing a remote code execution vulnerability if someone manages to inject unintended ruby code). – Holger Just Apr 04 '17 at 15:42
  • Also, the linked benchmark is seriously flawed since the expensive part of using `a.method("length").call`, namely the generation of the method object, is left out of the benchmark. If you include it in the loop, the fastest option will again be `send` respectively `public_send` – Holger Just Apr 04 '17 at 15:45