Forum: Ruby How do I pass the name of an instance variable into an object?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Glenn (Guest)
on 2009-01-01 05:20
(Received via mailing list)
Hi,

Suppose I wanted to create a method for an object that allowed me to
pass in the name of an instance variable and to perform some task on the
variable.  For the sake of simplicity, let's say that I'd like to be
able to print out the value of the specified instance variable.  Also,
I'd want the method to raise an exception if the name of the variable
getting passed into the object is not actually an instance variable in
the object.

The class would look something like this:

class SomeClass
  def initialize
    @a = 1
    @b = 'xxx'
  end

  def print_instance_variables(obj)
     # some code goes here
  end
end

And here's how I'd like to be able to use it:

x = SomeClass.new
x.print_instance_variables(:a) # writes the value of @a to the console
x.print_instance_variables(:b) # writes the value of @b to the console
x.print_instance_variables(:a, :b) # writes the values of @a and @b to
the console
x.print_instance_variables(:z) # causes an exception because there is
no@z

Any suggestions would be greatly appreciated.

Thanks,

Glenn
Joshua A. (Guest)
on 2009-01-01 06:52
Glenn,

There may be a much better way to do this, but here's what I threw
together:

class SomeClass
  attr_accessor :a, :b
  def initialize
    @a = 'A'
    @b = 'B'
  end

  def print_instance_variable(variable)
    if instance_variables.include?("@#{variable}")
      puts self.send("#{variable}")
    else
      raise 'Not an instance variable.'
    end
  end
end

x = SomeClass.new
x.print_instance_variable('a')

Hope that at least points you in the right direction.

-- Josh
http://iammrjoshua.com



Glenn wrote:
> Hi,
>
> Suppose I wanted to create a method for an object that allowed me to
> pass in the name of an instance variable and to perform some task on the
> variable.  For the sake of simplicity, let's say that I'd like to be
> able to print out the value of the specified instance variable.  Also,
> I'd want the method to raise an exception if the name of the variable
> getting passed into the object is not actually an instance variable in
> the object.
>
> The class would look something like this:
>
> class SomeClass
>   def initialize
>     @a = 1
>     @b = 'xxx'
>   end
>
>   def print_instance_variables(obj)
>      # some code goes here
>   end
> end
>
> And here's how I'd like to be able to use it:
>
> x = SomeClass.new
> x.print_instance_variables(:a) # writes the value of @a to the console
> x.print_instance_variables(:b) # writes the value of @b to the console
> x.print_instance_variables(:a, :b) # writes the values of @a and @b to
> the console
> x.print_instance_variables(:z) # causes an exception because there is
> no@z
>
> Any suggestions would be greatly appreciated.
>
> Thanks,
>
> Glenn
Greg D. (Guest)
on 2009-01-01 06:59
(Received via mailing list)
On Wed, Dec 31, 2008 at 9:18 PM, Glenn <removed_email_address@domain.invalid> 
wrote:
>  end
> x.print_instance_variables(:b) # writes the value of @b to the console
> x.print_instance_variables(:a, :b) # writes the values of @a and @b to the console
> x.print_instance_variables(:z) # causes an exception because there is no@z
>
> Any suggestions would be greatly appreciated.


class SomeClass
  def initialize
    @a = 1
    @b = 'xxx'
  end

  def print_instance_variables( *args )
    args.each do |arg|
      raise unless instance_variable_defined?( "@#{ arg }" )
      puts self.instance_variable_get( "@#{ arg }" )
    end
  end

end

x = SomeClass.new
x.print_instance_variables( :a )
x.print_instance_variables( :b )
x.print_instance_variables( :a, :b )
x.print_instance_variables( :z )
Joshua A. (Guest)
on 2009-01-01 07:49
Thanks Greg! Much nicer than what I threw together.

-- Josh
http://iammrjoshua.com

Greg D. wrote:
> On Wed, Dec 31, 2008 at 9:18 PM, Glenn <removed_email_address@domain.invalid> wrote:
>>  end
>> x.print_instance_variables(:b) # writes the value of @b to the console
>> x.print_instance_variables(:a, :b) # writes the values of @a and @b to the console
>> x.print_instance_variables(:z) # causes an exception because there is no@z
>>
>> Any suggestions would be greatly appreciated.
>
>
> class SomeClass
>   def initialize
>     @a = 1
>     @b = 'xxx'
>   end
>
>   def print_instance_variables( *args )
>     args.each do |arg|
>       raise unless instance_variable_defined?( "@#{ arg }" )
>       puts self.instance_variable_get( "@#{ arg }" )
>     end
>   end
>
> end
>
> x = SomeClass.new
> x.print_instance_variables( :a )
> x.print_instance_variables( :b )
> x.print_instance_variables( :a, :b )
> x.print_instance_variables( :z )
Glenn (Guest)
on 2009-01-01 16:25
(Received via mailing list)
Hi,

Thanks for your help!

I have a followup question.  Can anyone tell me how I could create a
method that would allow me to add instance variables to an object?

The method would look something like this:

def add_instance_variable(x, y)
 # code goes here
end

In this example, x would be what I'd like to call the variable and y
would be the value of the new variable.

Thanks again,

Glenn



________________________________
From: Greg D. <removed_email_address@domain.invalid>
To: ruby-talk ML <removed_email_address@domain.invalid>
Sent: Wednesday, December 31, 2008 11:58:11 PM
Subject: Re: How do I pass the name of an instance variable into an
object?

On Wed, Dec 31, 2008 at 9:18 PM, Glenn <removed_email_address@domain.invalid> 
wrote:
>  end
> x.print_instance_variables(:b) # writes the value of @b to the console
> x.print_instance_variables(:a, :b) # writes the values of @a and @b to the console
> x.print_instance_variables(:z) # causes an exception because there is no@z
>
> Any suggestions would be greatly appreciated.


class SomeClass
  def initialize
    @a = 1
    @b = 'xxx'
  end

  def print_instance_variables( *args )
    args.each do |arg|
      raise unless instance_variable_defined?( "@#{ arg }" )
      puts self.instance_variable_get( "@#{ arg }" )
    end
  end

end

x = SomeClass.new
x.print_instance_variables( :a )
x.print_instance_variables( :b )
x.print_instance_variables( :a, :b )
x.print_instance_variables( :z )
Sebastian H. (Guest)
on 2009-01-01 17:06
(Received via mailing list)
Glenn wrote:
> Can anyone tell me how I could create a method that would allow me to add
> instance variables to an object?

object.instance_variable_set(:@variable_name, "value")

HTH,
Sebastian
Suman G. (Guest)
on 2009-01-01 19:48
(Received via mailing list)
i just tried putting everything together and it worked great.
I thought i will share the consolidated code, so here it is:

class SomeClass
  def initialize
    @first = 'first variable'
    @second = 'second variable'
  end

  def print_instance_variable(*args)
    args.each do |arg|
      begin
        raise unless instance_variable_defined?("@#{arg}")
        puts self.instance_variable_get("@#{arg}")
      rescue => ex
        puts  "#{ex.class}: #{ex.message}"
      end
    end
  end

  def add_instance_variable(name, initial_value)
    raise if instance_variable_defined?("@#{name}")
    self.instance_variable_set("@#{name}", "#{initial_value}")
  end
end


x = SomeClass.new
x.print_instance_variable(:first)
x.print_instance_variable(:second)

puts "\n****************** printing both values in one method call
*************"
x.print_instance_variable :first, :second

puts "\n*************** should throw an exception, because the
instance variable is undefined **************"
x.print_instance_variable :third


x.add_instance_variable(:third, "third value")

puts "\n*************** should print the third instance
variable**************"
x.print_instance_variable :third
Glenn (Guest)
on 2009-01-01 20:50
(Received via mailing list)
Excellent!  Thanks so much for your help.

I noticed that the class of the variable always seems to be String when
I use add_instance_variable.  When I use instance_variable_set, though
it seems to preserve the class of the object in thee 2nd parameter.

In this case, x is a Fixnum:

s = SomeClass.new
s.instance_variable_set('@x', 22)

In this case, though, x is a String:

s = SomeClass.new
s.add_instance_variable(:x, 22)

I think that this is because of the quotes around initial_value in this
line:

self.instance_variable_set("@#{name}", "#{initial_value}")


When I rewrote the line as:

self.instance_variable_set("@#{name}", initial_value )


It maintains the original class of that 2nd parameter.  Do you think
that there is any harm in leaving those quotes off?

Glenn



________________________________
From: Suman G. <removed_email_address@domain.invalid>
To: ruby-talk ML <removed_email_address@domain.invalid>
Sent: Thursday, January 1, 2009 12:46:51 PM
Subject: Re: How do I pass the name of an instance variable into an
object?

i just tried putting everything together and it worked great.
I thought i will share the consolidated code, so here it is:

class SomeClass
  def initialize
    @first = 'first variable'
    @second = 'second variable'
  end

  def print_instance_variable(*args)
    args.each do |arg|
      begin
        raise unless instance_variable_defined?("@#{arg}")
        puts self.instance_variable_get("@#{arg}")
      rescue => ex
        puts  "#{ex.class}: #{ex.message}"
      end
    end
  end

  def add_instance_variable(name, initial_value)
    raise if instance_variable_defined?("@#{name}")
    self.instance_variable_set("@#{name}", "#{initial_value}")
  end
end


x = SomeClass.new
x.print_instance_variable(:first)
x.print_instance_variable(:second)

puts "\n****************** printing both values in one method call
*************"
x.print_instance_variable :first, :second

puts "\n*************** should throw an exception, because the
instance variable is undefined **************"
x.print_instance_variable :third


x.add_instance_variable(:third, "third value")

puts "\n*************** should print the third instance
variable**************"
x.print_instance_variable :third
Sebastian H. (Guest)
on 2009-01-01 21:09
(Received via mailing list)
Glenn wrote:
> I think that this is because of the quotes around initial_value in this
> line:
> self.instance_variable_set("@#{name}", "#{initial_value}")
> [...]
> Do you think that there is any harm in leaving those quotes off?

Not at all. The only reason for them to be there in the first place
would be
to convert the value to a string (though initial_value.to_s would be a
more
readable way to do the same thing, in my opinion). Since you don't want
that,
there is no downside to removing them.

HTH,
Sebastian
This topic is locked and can not be replied to.