Returning symbols

I want to write a method to store a list of some instance variables in
an Array that will later be run through to access their data. Normally
in another language I would do this by passing them by reference when I
store them into the Array.

Using the object_id doesn't work because that's to the object the
variable is pointing to and this may change.
So, to sum it up:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

thanks,
Daniel

You could use a closure, but more typically you'd want to enapsulate he set of variables into a class and return that class.

Cheers

Dave

···

On Aug 16, 2004, at 7:47, Daniel Cremer wrote:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

Hi,

I want to write a method to store a list of some instance variables in an
Array that will later be run through to access their data. Normally in
another language I would do this by passing them by reference when I store
them into the Array.

Using the object_id doesn't work because that's to the object the variable
is pointing to and this may change. So, to sum it up:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

thanks,
Daniel

You can use the name as a string or symbol, and retrieve
the value with instance_variable_get.

ri instance_variable_get

------------------------------------------- Object#instance_variable_get
     obj.instance_variable_get(symbol) => obj

···

On Mon, 16 Aug 2004 21:47:59 +0900, Daniel Cremer wrote:
------------------------------------------------------------------------
     Returns the value of the given instance variable (or throws a
     NameError exception). The @ part of the variable name should be
     included for regular instance variables

        class Fred
          def initialize(p1, p2)
            @a, @b = p1, p2
          end
        end
        fred = Fred.new('cat', 99)
        fred.instance_variable_get(:@a) #=> "cat"
        fred.instance_variable_get("@b") #=> 99

Cheers,
KB

Daniel Cremer <daniel@danielcremer.com> writes:

I want to write a method to store a list of some instance variables in
an Array that will later be run through to access their data. Normally
in another language I would do this by passing them by reference when I
store them into the Array.

Using the object_id doesn't work because that's to the object the
variable is pointing to and this may change.
So, to sum it up:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

thanks,
Daniel

It's kind of a hack, and you should avoid using it, but

class Box
  def initialize (&accessor)
    @accessor = accessor
  end

  def set! (new)
    @accessor.call new
  end

  def get
    @accessor.call
  end
end

class Object
  def box (variable)
    Box.new do |*value|
      if value.empty?
        instance_variable_get variable
      else
        instance_variable_set variable, value.first
      end
    end
  end
end

foo = Foo.new

=> #<Foo:0x402f94c4 @a=5>

box = foo.box(:@a)

=> #<Box:0x402f68dc @accessor=#<Proc:0x4030f530@./boxes.rb:18>>

box.get

=> 5

box.set! 10

=> 10

box.get

=> 10

foo.instance_variable_get(:@a)

=> 10

class C
  attr_accessor :a, :b, :c
  def initialize
    @a, @b, @c = 1, 2, 3
  end
  def bump
    @a, @b, @c = 100, 200, 300
  end
  def ref
    return [ lambda { @a }, lambda { @b }, lambda { @c } ]
  end
end

c = C.new
v = c.ref
v.each { |q| puts q.call }
c.bump
v.each { |q| puts q.call }

···

On Monday 16 August 2004 08:47 am, Daniel Cremer wrote:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

--
T.

Daniel Cremer wrote:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

For ordinary variables you can use the code that I attached.

thanks,
Daniel

Regards,
Florian Gross

variable.rb (949 Bytes)

binding_of_caller.rb (2 KB)

"Daniel Cremer" <daniel@danielcremer.com> schrieb im Newsbeitrag
news:1092660434.3941.27.camel@linux.site...

I want to write a method to store a list of some instance variables in
an Array that will later be run through to access their data. Normally
in another language I would do this by passing them by reference when I
store them into the Array.

Using the object_id doesn't work because that's to the object the
variable is pointing to and this may change.
So, to sum it up:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

If I do understand correctly you want to store "self" together with the
information which members of "self" to retrieve. Others presented solutions
already, here is another one that is similar to the closure approach in that
it uses an array of elements that store "self" and an accessor for a certain
value but uses method instances instead:

class Foo
  attr_accessor :bar, :baz, :name
end

f = Foo.new

accessors = [:bar, :baz, :name].map { |s| f.method s }

p accessors.map { |acc| acc.call }

f.bar = "bar"
f.baz = "baz"
f.name = "name"

p accessors.map { |acc| acc.call }

f.bar = "BAR"
f.baz = "BAZ"
f.name = "NAME"

p accessors.map { |acc| acc.call }

Dunno which is more efficient though.

Kind regards

    robert

> Is there a way to get variables to return their symbol so you can access
> what they will be referencing in the future ?

class C
  attr_accessor :a, :b, :c
  def initialize
    @a, @b, @c = 1, 2, 3
  end
  def bump
    @a, @b, @c = 100, 200, 300
  end
  def ref
    return [ lambda { @a }, lambda { @b }, lambda { @c } ]
  end
end

c = C.new
v = c.ref
v.each { |q| puts q.call }
c.bump
v.each { |q| puts q.call }

Interesting example... What I don't understand is how would you
implement object pools in Ruby ? If I understand correctly with object
pools you often have data representing state stored separately. Then
when needed you can grab an instance of the object from the pool and
populate it with this data.
For an example like that I would like to have a base-class that
implements a persist() method. This way developers working on a class
can inherit this class and simply pass the objects representing state to
this persist() method.

def persist(*state_objs)
...
    persistent_objects = Array.new()
    state_objs.each { |obj| persistent_objects << obj }
  ...
end

From then on it could be included into object pools with no further work

from the developer.

But this is were I have problems. Implementing this in the base class
such that it can take any list of variables without any knowledge of
their names and being able to get back to the contents of the variables
to store the state before returning the object to the pool.
I hope this makes sense, I might be confusing myself :slight_smile:

···

On Mon, 2004-08-16 at 14:53, T. Onoma wrote:

On Monday 16 August 2004 08:47 am, Daniel Cremer wrote:

On Mon, 2004-08-16 at 14:04, Dave Thomas wrote:

You could use a closure, but more typically you'd want to enapsulate he
set of variables into a class and return that class.

Could someone elaborate on the part about returning a class. I'm not
sure if I captured the full meaning.

thanks,
Daniel

what does this give you over this?

   ~ > cat a.rb
   class C
     VARS = :a, :b, :c
     VARS.each{|v| attr_accessor v}
     def initialize
       @a, @b, @c = 1, 2, 3
     end
     def bump
       @a, @b, @c = 100, 200, 300
     end
     def ref
       VARS
     end
   end

   c = C.new
   vars = c.ref
   vars.each { |v| puts(c.send(v)) }
   c.bump
   vars.each { |v| puts(c.send(v)) }

   ~ > ruby a.rb
   1
   2
   3
   100
   200
   300

what am i missing here?

-a

···

On Mon, 16 Aug 2004, T. Onoma wrote:

On Monday 16 August 2004 08:47 am, Daniel Cremer wrote:

Is there a way to get variables to return their symbol so you can access
what they will be referencing in the future ?

class C
attr_accessor :a, :b, :c
def initialize
   @a, @b, @c = 1, 2, 3
end
def bump
   @a, @b, @c = 100, 200, 300
end
def ref
   return [ lambda { @a }, lambda { @b }, lambda { @c } ]
end
end

c = C.new
v = c.ref
v.each { |q| puts q.call }
c.bump
v.each { |q| puts q.call }

--
T.

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

Reference to c. With the lambda example the context is embedded. Send on the
other hand requires the applicable object be remembered separately.

  vars.each { |q| puts q.call } # no c
  vars.each { |v| puts(c.send(v)) }

···

On Monday 16 August 2004 10:51 am, Ara.T.Howard wrote:

what does this give you over this?
...
what am i missing here?

--
T.

Ok I think I cleared my brain a bit on my particular example and did a
quick implementation:

···

On Mon, 2004-08-16 at 15:23, Daniel Cremer wrote:

... What I don't understand is how would you
implement object pools in Ruby ? If I understand correctly with object
pools you often have data representing state stored separately. Then
when needed you can grab an instance of the object from the pool and
populate it with this data.
For an example like that I would like to have a base-class that
implements a persist() method. This way developers working on a class
can inherit this class and simply pass the objects representing state to
this persist() method.

def persist(*state_objs)
...
    persistent_objects = Array.new()
    state_objs.each { |obj| persistent_objects << obj }
  ...
end

>From then on it could be included into object pools with no further work
from the developer.

But this is were I have problems. Implementing this in the base class
such that it can take any list of variables without any knowledge of
their names and being able to get back to the contents of the variables
to store the state before returning the object to the pool.
I hope this makes sense, I might be confusing myself :slight_smile:

--------------------------------
require 'set'

class MyBaseClass
  @@persist = Set.new()
  
  def MyBaseClass.persist(*symbol)
    symbol.each do |symbol|
      instance_symbol = "@" + symbol.to_s
      @@persist.add(instance_symbol)
    end
  end

  def return_persistent_vars()
    output = Array.new()
    @@persist.each {|val| output << self.instance_variable_get(val) }
    return output
  end
end

class ObjPoolObj < MyBaseClass
  attr_accessor :var1, :var2, :var3
  persist :var1, :var2

  def initialize
    @var1 = "hello"
    @var2 = "world"
    @var3 = "nothingHere"
  end

end

test_obj = ObjPoolObj.new()
puts test_obj.return_persistent_vars() #=> hello
                                             #=> world

test_obj.var1 = "hellomodified"
puts test_obj.return_persistent_vars() #=> hellomodified
                                             #=> world

---------------------------

The part I find cool is being able to call: "persist :var1, :var2" in
the same manner as attr_accessor. Of course the whole storing of the
data and stuffing it back into the object from the pool would need to be
implemented but that should be simple enough. I'll think about
generalising this stuff...
thanks for keeping my neurons firing.
Daniel