0

I want to have a hash my_statement as below:

my_statement = %|{:foo=>\#{bar_array}}|

where :foo is the key and the value is to be substituted with the value of bar_array later. After I later define bar_array = ["a","b"], I do an eval on this statement, and want it to show the following:

eval(my_statement)
# => {:foo=>["a", "b"]}

I need to escape the variable bar_array so that it evaluates not when my_statement is assigned but rather when eval is called on it. I can't seem to get the escaping of the variable. I tried \#, #, \\#.

The background of why I am doing this: I have several statically defined charts backed by SOLR queries. I took the approach to define these queries in a serializable column in the database (again they "never" change). There are actually two levels of queries; the first level which gets "all" data for that query; and the second level which is based on the user selecting some data (off of a chart) from the first query - i.e., I need a variable to be part of the second query. Sometimes (like in this example) the variable will contain an array.

Arthur Frankel
  • 4,695
  • 6
  • 35
  • 56

2 Answers2

2

Perhaps try string formatting instead. It is not evaluated on creation but rather later.

statement = %|{:foo => %s}|
array = ["a", "b"]
eval(statement % array.inspect) #=> {:foo => ["a", "b"]}
array = [1,2,3]
eval(statement % array.inspect) #=> {:foo => [1, 2, 3]}

Here's another SO question that deals with the above concept

I get highly nervous when I see eval so I would recommend finding some other way of accomplishing this! However, this should work if you deem there to be no other means.

Community
  • 1
  • 1
Charles Caldwell
  • 16,649
  • 4
  • 40
  • 47
2

There are more straightforward ways to do that.

(1) Make it a method

def statement; {foo: @array} end
...
# later in the code
@array = %w[a b]
statement # => {:foo => ["a", "b"]}

(2) Use a proc

statement = ->{{foo: @array}}
...
# later in the code
@array = %w[a b]
statement.call # => {:foo => ["a", "b"]}
sawa
  • 165,429
  • 45
  • 277
  • 381
  • 1
    Much better than all that mucking around with `eval`! =) – Charles Caldwell May 06 '13 at 17:29
  • 1
    I like this, but (again sorry I didn't add some background initially) I don't think I can set up the instance var as part of my serialized query. I believe it will look for the value on load initially. – Arthur Frankel May 06 '13 at 17:36