# Instance\_variables doesn't return unassigned variables

**URL:** <https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792>\
**Category:** Ruby\
**Created:** [May 10, 2007, 12:00pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792 "2007-05-10T12:00:26Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 10, 2007, 12:00pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/1 "2007-05-10T12:00:26Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 10, 2007, 12:40pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/2 "2007-05-10T12:40:54Z")

</div>

On 5/10/07, Bernd [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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.

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/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 10, 2007, 1:04pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/3 "2007-05-10T13:04:58Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 10, 2007, 7:40pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/4 "2007-05-10T19:40:09Z")

</div>

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

> x.first = “test”  
> puts x.instance\_variables
> 
> the output was only
> 
> @first

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 @.

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 10, 2007, 2:06pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/5 "2007-05-10T14:06:06Z")

</div>

On 10.05.2007 12:00, Bernd wrote:

> 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.

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

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 10, 2007, 11:59pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/6 "2007-05-10T23:59:39Z")

</div>

On 5/10/07, Jesse M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > x = ABC.new  
> > x.first = “test”  
> > puts x.instance\_variables
> > 
> > the output was only
> > 
> > @first
> 
> You could deduce them by looking for methods that end in an equals:  
> 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

\>

HTH  
Robert

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 11, 2007, 2:37pm UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/7 "2007-05-11T14:37:18Z")

</div>

> …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

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 11, 2007, 10:46am UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/8 "2007-05-11T10:46:51Z")

</div>

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

> > >
> 
> induce the creation of an instance variable with that name.  
> orig\_attreader \*symbols  
> end
> 
> def attributes  
> @ **atts** || []  
> end  
> end

…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  
…

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 12, 2007, 4:47am UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/9 "2007-05-12T04:47:54Z")

</div>

On 5/11/07, Robert D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![bernd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/977dab/32.png) [@bernd](https://www.ruby-forum.com/u/bernd)\
**Post date:** [May 13, 2007, 10:45am UTC](https://www.ruby-forum.com/t/instance-variables-doesnt-return-unassigned-variables/103792/10 "2007-05-13T10:45:05Z")

</div>

On 5/12/07, Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > You do that for him, I would think it is worth to distinguish them.  
> > 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.  
> > 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.

> In this way, Ruby is more like Self than those other languages. Self  
> of classes, mixins, etc.  
> 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/](http://talklikeaduck.denhaven2.com/)

Cheers  
Robert
