Access a variables name?

is it possible to access the variable-name of an object?

like (pseudo ruby code):

@instance_var = []
@instance_var.name = ‘@instance_var

  • m.r.
···


Using M2, Opera’s revolutionary e-mail client: http://www.opera.com/m2/

meinrad.recheis wrote:

is it possible to access the variable-name of an object?

An object instance can be referenced by multiple variables, and not only
by variables the reference could be an item in an hash or array etc. In
other words I don’t think so… But I’m a total rubynewbee, so I’m
probably wrong ;).

Regards,

Peter

( is this ‘==’ ? )

I don’t really fully understand what you mean, but what I get is that
you’d like to manipulate variables themselves (not the objects they
point to). Take into account that Ruby isn’t statically typed, so
variables don’t have properties per se (types), only the objects
they point to. Moreover several variables can refer to the same
object…

The closest to what you ask would be using Object#instance_variables to
get a list of the defined instance variables for a given object.

But as I told before, I don’t really get what you intend to do, please
clarify :slight_smile:

Assuming that you meant that
@instance_var.name == ‘@instance_var
you can do something like the following (but have no idea what it could
be used for, and do see it as quite evil in fact).

batsman@tux-chan:/tmp$ expand -t2 ab.rb
module InstanceNameInfo
def attr_with_info(*ids)
ids.each do |x|
class_eval <<-EOF
def #{x}
obj = @#{x}.dup
class << obj
def name
“@#{x}”
end
end
obj
end
EOF
end
end

end

class Foo
extend InstanceNameInfo
def initialize
@foo = “asdas”
@bar = “aaa”
end

attr_with_info :foo, :bar
end

a = Foo.new
puts “#{a.foo} => #{a.foo.name}”
puts “#{a.bar} => #{a.bar.name}”
batsman@tux-chan:/tmp$ ruby ab.rb
asdas => @foo
aaa => @bar

You might want to add a singleton method directly to the
objects, etc…

Sorry if I missed the point completely.

···

On Thu, May 08, 2003 at 04:24:02AM +0900, meinrad.recheis wrote:

is it possible to access the variable-name of an object?

like (pseudo ruby code):

@instance_var =
@instance_var.name = ‘@instance_var

_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

To kick or not to kick…
– Somewhere on IRC, inspired by Shakespeare

ok. thanks so far for comments.

it was an idea that was not so clear in fact, so i tell you my motivation:

i want to configure objects with different values from files.
it is possible to configure an object by loading a file and evaluating it’s
content inside that object:

File: configuration.rb

@var1 = [1,2]
@var2 = {1=>@var1} …

after evaluating this files lines inside the object’s namespace @var1 and
@var2 do exist as names.
maybe i have an interactive program and the user changes values for @var1
or @var2.

now i want to overwrite my configuration.rb with the new values that the
names @var1 and @var2 reference. so that configuration.rb could be
evaluated again.

i call this kind of configuration files plugins, because they are mightier
than simple configfiles (like xml) which contain only data. plugins could
also contain executable code. but code could not be saved back to the file.

plugins are straight forward, and cool if there are no security issues, why
not?

saving a hash to a interpretable string is no problem using #inspect
my only problem is saving the names of the object, that are in fact
existent in the namespace.

is that a little clearer?

  • m.r.

class Foo
attr_accessor :bar
end
a = Foo.new
a.bar = 1
p a #>> #<Foo:0x81c6600 @bar=1>
p a.instance_variables #>> [“@bar”]
a.instance_eval {@bar} #>> 1
a.instance_variable_get(“@bar”) #>> 1
a.instance_variable_set(“@baz”,2)
p a #>> <Foo:0x81c6600 @baz=2, @bar=1>

The last two examples show reading/writing instance variables by name, is
that what you were trying to do?

Regards,

Brian.

···

On Thu, May 08, 2003 at 04:24:02AM +0900, meinrad.recheis wrote:

is it possible to access the variable-name of an object?

like (pseudo ruby code):

@instance_var =
@instance_var.name = ‘@instance_var

[…]

i want to configure objects with different values from files.
it is possible to configure an object by loading a file and evaluating it’s
content inside that object:

File: configuration.rb

@var1 = [1,2]
@var2 = {1=>@var1} …

after evaluating this files lines inside the object’s namespace @var1 and
@var2 do exist as names.
maybe i have an interactive program and the user changes values for @var1
or @var2.

now i want to overwrite my configuration.rb with the new values that the
names @var1 and @var2 reference. so that configuration.rb could be
evaluated again.

[…]

saving a hash to a interpretable string is no problem using #inspect
my only problem is saving the names of the object, that are in fact
existent in the namespace.

Got it now :slight_smile:

batsman@tux-chan:/tmp$ expand -t2 ac.rb

class Foo
def iv_name(iv)
instance_variables.each do |x|
return x if instance_eval(x).id == iv.id
end
nil
end

def dump(var, subst = false)
name = iv_name(var)
return name if name && subst
case var
when Array
“[” + var.map {|x| self.dump(x,true)}.join(“,”) + “]”
when Hash
“{” + var.map {|k, v| self.dump(k,true) + “=>” +
self.dump(v,true)}.join(“,”) + “}”
else
var.inspect
end
end
end

file = <<-EOF
@var1 = [1,2]
@var2 = {1=>@var1}
@var3 = {@var1 => @var2}
EOF

someobj = Foo.new
someobj.instance_eval file

puts “Reconstructed file:”
someobj.instance_variables.sort.each do |x|
repr = someobj.dump(someobj.instance_eval(x))
puts “#{x} = #{repr}”
end

batsman@tux-chan:/tmp$ ruby ac.rb
Reconstructed file:
@var1 = [1,2]
@var2 = {1=>@var1}
@var3 = {@var1=>@var2}

You can make it cleaner if you make “dump” (or better find another name
so it doesn’t conflict with Marshal) an instance method of all the
classes involved. But then you have to pass around the object these iv.
live in so they can resolve names if needed.

That would be more OO and elegant, but probably overkill.

Can post this too if you want, but that’ll be tomorrow :slight_smile:

···

On Thu, May 08, 2003 at 06:05:15AM +0900, meinrad.recheis wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

By golly, I’m beginning to think Linux really is the best thing since
sliced bread.
– Vance Petree, Virginia Power

Brian Candler wrote:

is it possible to access the variable-name of an object?

like (pseudo ruby code):

@instance_var =
@instance_var.name = ‘@instance_var

class Foo
attr_accessor :bar
end
a = Foo.new
a.bar = 1
p a #>> #<Foo:0x81c6600 @bar=1>
p a.instance_variables #>> [“@bar”]

ok, this is actually all i need, for my purpose

a.instance_eval {@bar} #>> 1
a.instance_variable_get(“@bar”) #>> 1
a.instance_variable_set(“@baz”,2)

but, what’s that? i didn’t find instance_variable_get/set in ruby’s
documentation

p a #>> <Foo:0x81c6600 @baz=2, @bar=1>

The last two examples show reading/writing instance variables by name, is
that what you were trying to do?

yes exactly. thanks brian

···

On Thu, May 08, 2003 at 04:24:02AM +0900, meinrad.recheis wrote:

Regards,

Brian.

Mauricio Fernández wrote:
[…]

batsman@tux-chan:/tmp$ expand -t2 ac.rb

class Foo
def iv_name(iv)
instance_variables.each do |x|
return x if instance_eval(x).id == iv.id
end
nil
end

def dump(var, subst = false)
name = iv_name(var)
return name if name && subst
case var
when Array
“[” + var.map {|x| self.dump(x,true)}.join(“,”) + “]”
when Hash
“{” + var.map {|k, v| self.dump(k,true) + “=>” +
self.dump(v,true)}.join(“,”) + “}”
else
var.inspect
end
end
end

file = <<-EOF
@var1 = [1,2]
@var2 = {1=>@var1}
@var3 = {@var1 => @var2}
EOF

someobj = Foo.new
someobj.instance_eval file

puts “Reconstructed file:”
someobj.instance_variables.sort.each do |x|
repr = someobj.dump(someobj.instance_eval(x))
puts “#{x} = #{repr}”
end

thank you, that s very helpful.

batsman@tux-chan:/tmp$ ruby ac.rb
Reconstructed file:
@var1 = [1,2]
@var2 = {1=>@var1}
@var3 = {@var1=>@var2}

[…]

  • m.r.

It’s a recent feature - it’s not in 1.6.8 but it’s in 1.8.0p2

You can query directly what methods are available in an object: e.g.

irb(main):005:0> class Foo; end
=> nil
irb(main):006:0> a=Foo.new
=> #Foo:0x81b49dc
irb(main):007:0> a.public_methods
=> [“untaint”, “kind_of?”, “type”, “instance_variable_get”, “inspect”,
“frozen?”, “taint”, “send”, “private_methods”, “id”, “method”, “=~”,
“to_a”, “eql?”, “dup”, “hash”, “singleton_methods”, “display”, “nil?”,
“freeze”, “is_a?”, “class”, “instance_variable_set”, “methods”, “send”,
“instance_eval”, “extend”, “object_id”, “instance_variables”,
“instance_of?”, “to_s”, “copy_object”, “id”, “protected_methods”, “equal?”,
“respond_to?”, “clone”, “tainted?”, “==”, “public_methods”, “===”]

···

On Thu, May 08, 2003 at 02:48:39PM +0900, Meinrad Recheis wrote:

a.instance_variable_get(“@bar”) #>> 1
a.instance_variable_set(“@baz”,2)

but, what’s that? i didn’t find instance_variable_get/set in ruby’s
documentation

So, this is a new way to circument access privelages?

class C
def c; puts @c; end
end

c = C.new
c.instance_variable_set(“@c”, 2)
c.instance_variable_get(“@c”) #=> 2

c.c #=> 2

···

On Thursday, 8 May 2003 at 15:54:56 +0900, Brian Candler wrote:

On Thu, May 08, 2003 at 02:48:39PM +0900, Meinrad Recheis wrote:

a.instance_variable_get(“@bar”) #>> 1
a.instance_variable_set(“@baz”,2)

It’s a recent feature - it’s not in 1.6.8 but it’s in 1.8.0p2


Jim Freeze

Economics is extremely useful as a form of employment for economists.
– John Kenneth Galbraith

No, not really. You’ve always been able to do it, with
Object#instance_eval.

tim@zaphod:~$ ruby -v
ruby 1.6.7 (2002-03-19) [i386-linux]

irb(main):001:0> class Foo
irb(main):002:1> def bar
irb(main):003:2> @bar
irb(main):004:2> end
irb(main):005:1> end
nil
irb(main):006:0> f = Foo.new
#Foo:0x40271c60
irb(main):007:0> f.instance_eval{ @bar = 7 }
7
irb(main):008:0> f.bar
7
irb(main):009:0>

Tim Bates

···

On Thu, May 08, 2003 at 07:07:37PM +0900, Jim Freeze wrote:

So, this is a new way to circument access privelages?


tim@bates.id.au

Right. This is yet another way to circumvent access privelages.
#send is another.

This method is even better (worse) than instance_eval,
it gives you a list of instance variable names.

···

On Thursday, 8 May 2003 at 19:33:43 +0900, Tim Bates wrote:

On Thu, May 08, 2003 at 07:07:37PM +0900, Jim Freeze wrote:

So, this is a new way to circument access privelages?

No, not really. You’ve always been able to do it, with
Object#instance_eval.


Jim Freeze

In seeking the unattainable, simplicity only gets in the way.
– Epigrams in Programming, ACM SIGPLAN Sept. 1982

We can just add it to our list of evil methods :slight_smile:

Seriously, I wouldn’t call this “a new way to circumvent access
privileges”. It is so easy to neglect them that they are mostly a hint
for the programmer (“you’re not expected to play with this, but had better
know what you’re doing otherwise”). This is good however as Ruby is
not only a man-machine language but also man-man (check ts’ postings :wink:

···

On Thu, May 08, 2003 at 09:05:56PM +0900, Jim Freeze wrote:

On Thursday, 8 May 2003 at 19:33:43 +0900, Tim Bates wrote:

On Thu, May 08, 2003 at 07:07:37PM +0900, Jim Freeze wrote:

So, this is a new way to circument access privelages?

No, not really. You’ve always been able to do it, with
Object#instance_eval.

Right. This is yet another way to circumvent access privelages.
#send is another.

This method is even better (worse) than instance_eval,
it gives you a list of instance variable names.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Never trust an operating system you don’t have sources for. :wink:
– Unknown source

I’m not trying to be contrary, but I would claim that it is ‘new’
simply because the method names are new.
Nevertheless, #instance_variables is a great tool for reflection.

···

On Thursday, 8 May 2003 at 21:43:05 +0900, Mauricio Fernández wrote:

On Thu, May 08, 2003 at 09:05:56PM +0900, Jim Freeze wrote:

On Thursday, 8 May 2003 at 19:33:43 +0900, Tim Bates wrote:

On Thu, May 08, 2003 at 07:07:37PM +0900, Jim Freeze wrote:

So, this is a new way to circument access privelages?

No, not really. You’ve always been able to do it, with
Object#instance_eval.

Right. This is yet another way to circumvent access privelages.
#send is another.

This method is even better (worse) than instance_eval,
it gives you a list of instance variable names.

We can just add it to our list of evil methods :slight_smile:

Seriously, I wouldn’t call this “a new way to circumvent access
privileges”. It is so easy to neglect them that they are mostly a hint
for the programmer (“you’re not expected to play with this, but had better
know what you’re doing otherwise”). This is good however as Ruby is
not only a man-machine language but also man-man (check ts’ postings :wink:


Jim Freeze

Nihilism should commence with oneself.