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'}
General Grievance
  • 4,555
  • 31
  • 31
  • 45
skaz
  • 21,962
  • 20
  • 69
  • 98

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,632
  • 1
  • 11
  • 20
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,468
  • 3
  • 24
  • 45
  • 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