Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Ruby Programming Language

instance_variables doesn't return unassigned variables


Hi,
I wrote a code like this.

class ABC
  attr_accesor :first, :second
end

when I wrote the following:

x = ABC.new
x.first = "test"
puts x.instance_variables

the output was only

@first

Is there a possibility to get also the unassigned variables? I mean,
they exist, but they are only nil.

Thanks so far
Bernd

--
Posted via http://www.ruby-forum.com/.

On 5/10/07, Bernd <burn@hotmail.com> wrote:

Ruby has no concept of 'declaring' instance variables (or any other
variable for that matter).  attr_accessor simply generates getter and
setter methods. The instance variable won't exist in a particular
instance until you call the setter, or directly assign to the instance
variable, such as in the initialize method.

In Ruby, instance variables don't exist until they are assigned.
Non-existant instance variables evaluate to nil, but just mentioning
them doesn't bring them into existance.

irb(main):001:0> class A
irb(main):002:1>   attr_accessor :i
irb(main):003:1>   end
=> nil
irb(main):004:0> a = A.new
=> #<A:0xb7b5aca4>
irb(main):005:0> a.instance_variables
=> []
irb(main):006:0> a.i
=> nil
irb(main):007:0> a.instance_variables
=> []
irb(main):008:0> a.i = "foo"
=> "foo"
irb(main):009:0> a.instance_variables
=> ["@i"]

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Behalf Of Bernd:
# class ABC
#   attr_accesor :first, :second

oops, watch the spell :)

# end
#
# when I wrote the following:
#
# x = ABC.new
# x.first = "test"
# puts x.instance_variables
#
# the output was only
# @first

sure

# Is there a possibility to get also the unassigned variables?

ruby is interpreted and dynamic and, in ruby, everything is an object, ergo, any object must come to life first. Variables only exist if you assign them something, or if they refer to something, it's where they get their life. We may go the backdoor route by inference..

irb(main):048:0> a=x.public_methods(false).select{|e| e["="]}.map{|e| "@"+e.chop}
=> ["@second", "@first"]
irb(main):049:0> b=x.instance_variables
=> ["@first"]
irb(main):050:0> a-b
=> ["@second"]  

thus @second is not yet vivified ..

but i am not sure if i am being rubyish here :(

# I mean, they exist, but they are only nil.

careful.   there is "exist" vs nil issue here. Eg, a method may return nil.  one may confuse methods with vars.

irb(main):005:0* class ABC
irb(main):006:1>   attr_accessor :first, :second
irb(main):007:1> end
=> nil
irb(main):009:0> x=ABC.new
=> #<ABC:0xb7d51990>
irb(main):010:0> x.first
=> nil
irb(main):015:0> x.instance_variables
=> []
irb(main):016:0> x.first=nil
=> nil
irb(main):017:0> x.first
=> nil
irb(main):018:0> x.instance_variables
=> ["@first"]

at this point @first now exist, but @second is not; ie, from the point of view of instance x of class ABC.

On 10.05.2007 12:00, Bernd wrote:

Additionally to the other replies: you can also do something like this:

irb(main):001:0> Pair = Struct.new :first, :second
=> Pair
irb(main):002:0> Pair.new.members
=> ["first", "second"]

Kind regards

        robert

On Thursday 10 May 2007 06:00, Bernd wrote:

You could deduce them by looking for methods that end in an equals:

irb(main):001:0> class ABC
irb(main):002:1>   attr_accessor :first, :second
irb(main):003:1> end
=> nil
irb(main):004:0> x = ABC.new
=> #<ABC:0xb7a02d48>
irb(main):010:0> x.methods.select { |m| /[\w_]+=$/.match m }
=> ["second=", "first="]

From there just strip of the = and prepend a @.

--
Jesse Merriman
jessemerri@warpmail.net
http://www.jessemerriman.com/

On 5/10/07, Jesse Merriman <jesse.d.merri@gmail.com> wrote:

Hmm that might not be a good idea, a method ending in equals does not
induce the creation of an instance variable with that name.
One could however put attr on steroids by creating a list of
attributes for the class.
Look at this quick and dirty hack do see if this could be helpfull for you

class Module
  alias_method :orig_attreader, :attr_reader
  def attr_reader *symbols
    @__atts__ ||= superclass.attributes.dup
    @__atts__ += symbols
    @__atts__.uniq!
    orig_attreader *symbols
  end

  def attributes
    @__atts__ || []
  end
end

class A
  attr_reader :a
  attr_reader :a, :b
  puts attributes.join(", ")
end

class B < A
  attr_reader :c
  def initialize
    @c = 42
  end
  puts attributes.join(", ")
end

puts B.new.c

<snip>


HTH
Robert
--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw
On 5/11/07, Robert Dober <robert.do@gmail.com> wrote:

> The idea is to have attributes and not instance variables, creating
> instance variables on the fly with the attr method will not
> distinguish them from other instance variables.

> I reckon that the only sense I could make from the post was when OP
> talked about the instance variables """created""" by the existence of
> accessors.
> You do that for him, I would think it is worth to distinguish them.
> Also have a look at inheritance, which is not handled by your code.

I'm not sure what the OP was really looking for.

My sense was that there wasn't a real requirement but a confusion over
why instance variables aren't created when you 'declare' an accessor.

Since the OP doesn't seem to have posted to this thread since the OP,
I don't know how much he really cares.

One of the interesting aspects of Ruby as compared to many other OO
languages such as Java, C++ and Smalltalk, is that instance variables
aren't actually declared, and are really dynamc properties of the
instances themselves rather than all instances of the class.

In the other mentioned languages, declaring instance variables creates
a template which is used to map the storage taken up by an object,
instance variable x is at offset y from the beginning of the object,
etc.

In Ruby instance variables are actually values in a hash which the
instance owns, and are placed there only when code executes which sets
the instance var.

In this way, Ruby is more like Self than those other languages.  Self
objects are really just a hash of slot names to slot values.  Dave
Ungar used to taunt Smalltalk implementors by asking them to add an
instance variable to the Object class, which usually crashed the
system.

Self went a little farther than Ruby in this regard since it unified
'instance' variables and methods, methods are just slots whose values
are executable.  In the same regard, all slot values are 'inheritable'
in the sense that objects can delegate to other objects when searching
for a named slot which is missing, which is how Self gets the effect
of classes, mixins, etc.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 5/12/07, Rick DeNatale <rick.denat@gmail.com> wrote:

So true and that is why I thought that having #instance_variables and
having my little #attributes has nothing to do with each other and
that indeed it might be a good idea to have an introspection tool
concerning the declared attributes of a *Class*.
I do not even touch instances or instancevariables in my
implementation but I provide a class based attributes introspection
method that respects the inheritance feature of attr_accessor (could
easily be extended for the other attr_* methods of course).

I do not really care if this is what OP wanted, though I thought that
was likely what he or somebody else wanted, I get easily confused, you
know.
Most important I felt that by trying to understand what seemed like a
nonsense request gave me the oppurtunity to do something useful.
Assuming (as dangerous as that might be) that this was what OP or
someone else had in mind.

Sorry if I am talking too many liberties.

Anyway if there was any confusion about the concept you have shed
quite some light on it.

> --
> Rick DeNatale

> My blog on Ruby
> http://talklikeaduck.denhaven2.com/

Cheers
Robert

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

On 2007-05-11 06:58:48 +0900 (Fri, May), Robert Dober wrote:

<snip>

..or, since the original problem was that no instance variable has been
created, just create it (in quick and dirty way):

class Module
 alias_method :orig_attr, :attr
 def attr(symbol, writable = false)
   orig_attr symbol, writable
   send symbol
 end
 ...

--
No virus found in this outgoing message.
Checked by 'grep -i virus $MESSAGE'
Trust me.

  application_pgp-signature_part
1K Download

> ..or, since the original problem was that no instance variable has been
> created, just create it (in quick and dirty way):

I have not written complicated code because I wanted to write
complicated code ;)

> class Module
>  alias_method :orig_attr, :attr
>  def attr(symbol, writable = false)
>    orig_attr symbol, writable
>    send symbol
>  end

The idea is to have attributes and not instance variables, creating
instance variables on the fly with the attr method will not
distinguish them from other instance variables.

I reckon that the only sense I could make from the post was when OP
talked about the instance variables """created""" by the existence of
accessors.
You do that for him, I would think it is worth to distinguish them.
Also have a look at inheritance, which is not handled by your code.

Cheers
Robert

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc