Setting "variable" global variable?

Hi !

I wonder if there is any way in Ruby of setting a “variable” global
variable at runtime, without using “eval”.

For example, could the following be done without “eval”:

  def my_set_global_variable(name, val)
  eval "#{name} = #{val.inspect}"
  end

  my_set_global_variable("$foo", [1,2,3])

  p $foo          # gives [1, 2, 3]

I would like to avoid “serializing” the “val” value above
(done with the “inspect” call), and assign the original "val"
directly instead.

For instance variables there is “instance_variable_set”, but is
there something corresponding for global variables ?

/Johan Holmberg

def global_variable_set(name, val)
eval(“proc { | x | $#{name} = x }”).call val
end
global_variable_set(“foo”, [1, 2, 3])

Johan Holmberg wrote:

···

Hi !

I wonder if there is any way in Ruby of setting a “variable” global
variable at runtime, without using “eval”.

For example, could the following be done without “eval”:

 def my_set_global_variable(name, val)
eval "#{name} = #{val.inspect}"
 end

 my_set_global_variable("$foo", [1,2,3])

 p $foo          # gives [1, 2, 3]

I would like to avoid “serializing” the “val” value above
(done with the “inspect” call), and assign the original “val”
directly instead.

For instance variables there is “instance_variable_set”, but is
there something corresponding for global variables ?

/Johan Holmberg

This is probably a stupid question, but wouldn’t it be simpler to use a global hash?

$myapp[name] = val

  • alan

Johan Holmberg holmberg@iar.se wrote in message news:Pine.GSO.4.50.0309241514380.29659-100000@pjakkur.iar.se

···

Hi !

I wonder if there is any way in Ruby of setting a “variable” global
variable at runtime, without using “eval”.

For example, could the following be done without “eval”:

  def my_set_global_variable(name, val)
eval "#{name} = #{val.inspect}"
  end

  my_set_global_variable("$foo", [1,2,3])

  p $foo          # gives [1, 2, 3]

def global_variable_set(name, val)
eval(“proc { | x | $#{name} = x }”).call val
end
global_variable_set(“foo”, [1, 2, 3])

or simply:

def global_variable_set(name, val)
eval “$#{name} = val”
end
global_variable_set(“foo”, [1, 2, 3])

but the original question was how to do it without the eval.

greetings
messju

···

On Thu, Sep 25, 2003 at 01:37:59AM +0900, Dan Doel wrote:

Johan Holmberg wrote:

Hi !

I wonder if there is any way in Ruby of setting a “variable” global
variable at runtime, without using “eval”.

For example, could the following be done without “eval”:

def my_set_global_variable(name, val)

eval “#{name} = #{val.inspect}”
end

my_set_global_variable("$foo", [1,2,3])

p $foo          # gives [1, 2, 3]

I would like to avoid “serializing” the “val” value above
(done with the “inspect” call), and assign the original “val”
directly instead.

For instance variables there is “instance_variable_set”, but is
there something corresponding for global variables ?

/Johan Holmberg

I think it is quite “ok”.
At least there is no extra copying (or serialization) of “val”
as in my original example.

I didn’t realize that the eval would “see” the value of “val”,
but apparently it does.

But I’m still interested in a solution without “eval”.

Thanks for the answers soo far,
/Johan Holmberg

···

On Thu, 25 Sep 2003, messju mohr wrote:

or simply:

def global_variable_set(name, val)
eval “$#{name} = val”
end
global_variable_set(“foo”, [1, 2, 3])

but the original question was how to do it without the eval.

Johan Holmberg wrote:

I think it is quite “ok”.
At least there is no extra copying (or serialization) of “val”
as in my original example.

This is probably obvious and likely irrelevant, but I will mention
that a caller could do something malicious by passing in an “evil”
string to be evaluated.

I didn’t realize that the eval would “see” the value of “val”,
but apparently it does.

It sees everything in the current binding. For example,
x = eval(“val”) is the same as x = val. (There are probably some
strange exceptions to this.)

But I’m still interested in a solution without “eval”.

My impression is that without a Ruby builtin, it is not really
possible without eval.

Exceptions might be:

  1. Maybe an extension could implement a method to do it.
  2. You could do something crazy like write an assignment to
    a file and then require the file… but it would fail under
    many circumstances.

Hal

Hi –

Johan Holmberg wrote:

I think it is quite “ok”.
At least there is no extra copying (or serialization) of “val”
as in my original example.

This is probably obvious and likely irrelevant, but I will mention
that a caller could do something malicious by passing in an “evil”
string to be evaluated.

I don’t want to be responsible for encouraging non-vigilance toward
things like this… but if val is a string, wouldn’t eval’ing val
just result in the string, not a further evaluation of the string?

a = “puts ‘hi’”
eval “b = a”

b is now “puts ‘hi’”, but ‘hi’ doesn’t get puts’d.

(Or is there another, more evil scenario I’m not thinking of?)

David

···

On Thu, 25 Sep 2003, Hal Fulton wrote:


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi –

Johan Holmberg wrote:

I think it is quite “ok”.
At least there is no extra copying (or serialization) of “val”
as in my original example.

This is probably obvious and likely irrelevant, but I will mention
that a caller could do something malicious by passing in an “evil”
string to be evaluated.

I don’t want to be responsible for encouraging non-vigilance toward
things like this… but if val is a string, wouldn’t eval’ing val
just result in the string, not a further evaluation of the string?

a = “puts ‘hi’”
eval “b = a”

b is now “puts ‘hi’”, but ‘hi’ doesn’t get puts’d.

(Or is there another, more evil scenario I’m not thinking of?)

he meant this line:

eval “$#{name} = val”

and passing sth. evil in “name”

greetings
messju

···

On Thu, Sep 25, 2003 at 03:15:25AM +0900, dblack@superlink.net wrote:

On Thu, 25 Sep 2003, Hal Fulton wrote:

David

dblack@superlink.net wrote:

Hi –

Johan Holmberg wrote:

I think it is quite “ok”.
At least there is no extra copying (or serialization) of “val”
as in my original example.

This is probably obvious and likely irrelevant, but I will mention
that a caller could do something malicious by passing in an “evil”
string to be evaluated.

I don’t want to be responsible for encouraging non-vigilance toward
things like this… but if val is a string, wouldn’t eval’ing val
just result in the string, not a further evaluation of the string?

a = “puts ‘hi’”
eval “b = a”

b is now “puts ‘hi’”, but ‘hi’ doesn’t get puts’d.

(Or is there another, more evil scenario I’m not thinking of?)

I was thinking of something like

set_global_variable(name,666)

where name is given a value like ‘1 + someprog; $foo’ which would
effectively result in:

eval(“$1 + someprog; $foo = 666”)

Hal

···

On Thu, 25 Sep 2003, Hal Fulton wrote:

Hi –

···

On Thu, 25 Sep 2003, Hal Fulton wrote:

dblack@superlink.net wrote:

I don’t want to be responsible for encouraging non-vigilance toward
things like this… but if val is a string, wouldn’t eval’ing val
just result in the string, not a further evaluation of the string?

a = “puts ‘hi’”
eval “b = a”

b is now “puts ‘hi’”, but ‘hi’ doesn’t get puts’d.

(Or is there another, more evil scenario I’m not thinking of?)

I was thinking of something like

set_global_variable(name,666)

where name is given a value like ‘1 + someprog; $foo’ which would
effectively result in:

eval(“$1 + someprog; $foo = 666”)

I realized this (that you meant name, not val) about halfway between
my office and class :slight_smile:

David


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav