# Instance variable access

**URL:** <https://www.ruby-forum.com/t/instance-variable-access/133338>\
**Category:** Ruby\
**Created:** [March 30, 2008, 1:05pm UTC](https://www.ruby-forum.com/t/instance-variable-access/133338 "2008-03-30T13:05:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 30, 2008, 1:05pm UTC](https://www.ruby-forum.com/t/instance-variable-access/133338/1 "2008-03-30T13:05:52Z")

</div>

After hee-hawing about with Facets’ instance variable extension  
methods, notably #instance\_assign, and looking at Rails own hee-hawing  
– #instance\_values and #instance\_variable\_names, and further  
conceiving of a couple more potential hee-haw-able candidate methods,  
I’ve duly concluded my earlier conception to be on spot – that  
instance variable access would by better if @ were a hash. Rather than  
hee-haw about it any longer, I implemented the idea. Here’s my first  
draft:

module Kernel

```
def instance_vars
  InstanceVariables.new(self)
end

```

end

class InstanceVariables

```
include Enumerable

def initialize(delegate)
  @delegate = delegate
end

def instance_delegate
  @delegate
end

def each
  @delegate.instance_variables.each do |name|
    yield(name[1..-1].to_sym,

```

@delegate.instance\_variable\_get(name))  
end  
end

```
def to_hash
  h = {}
  each do |name, value|
    h[name] = value
  end
  h
end

def [](name)
  name = atize(name)
  @delegate.instance_variable_get(name)
end

def []=(name, value)
  name = atize(name)
  @delegate.instance_varaible_set(name,value)
end

def <<(pair)
  name, value = *pair
  name = atize(name)
  @delegate.instance_varaible_set(name, value)
end

def update(hash)
  hash.each do |pair|
    self << pair
  end
end

def keys
  @delegate.instance_variables.collect do |name|
    name[1..-1].to_sym
  end
end

def names
  @delegate.instance_variables.collect do |name|
    name[1..-1]
  end
end

def values
  @delegate.instance_variables.collect do |name|
    @delegate.instance_variable_get(name)
  end
end

private

def atize(name)
  name !~ /^@/ ? "@#{name}" : name
end

```

end

For example:

class Contact  
attr\_accessor :name, :age, :phone  
def initialize(name, age, phone)  
@name, @age, @phone = name, age, phone  
end  
end

f1 = Contact.new(“John”, 30, “555-1212”)  
p f1.instance\_vars.to\_hash  
=\> {:phone=\>“555-1212”, :name=\>“John”, :age=\>30}

The code is not quite complete, but it’s clear how this is going –  
implementing access to an object’s instance variables in a way highly  
polymorphic to Hash.

I’m not too keen on the abbreviated term “instance\_vars”. I’m  
considering using the terms #instance\_state and InstanceState,  
instead, to differentiate it from #instance\_variables. I would also  
like to add a short method for access, perhaps **iv** or **at**. Or  
perhaps it should be a private method #iv. Also, maybe we should cache  
InstanceVariables.new(self)?

In any case, this seems like a hell of a lot better way of going about  
things. Adding additional constructs for working with instance  
variables becomes a matter fully isolated from Kernel.

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 30, 2008, 4:09pm UTC](https://www.ruby-forum.com/t/instance-variable-access/133338/2 "2008-03-30T16:09:46Z")

</div>

On Sun, Mar 30, 2008 at 1:05 PM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
Basically I like the idea.  
I know it is premature optimization but performance will hurt  
sometimes, so I would still overload Object in that cases.  
But in most cases this is a very clean and readable approach.

Nice job.

Robert

–  
[http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

* * *

Whereof one cannot speak, thereof one must be silent.  
Ludwig Wittgenstein

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 30, 2008, 5:05pm UTC](https://www.ruby-forum.com/t/instance-variable-access/133338/3 "2008-03-30T17:05:22Z")

</div>

On Sun, Mar 30, 2008 at 10:09 AM, Robert D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> On Sun, Mar 30, 2008 at 1:05 PM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
> Basically I like the idea.

I don’t.

This sort of thing encourages thinking about objects as data  
structures rather than objects and discourages good OO implementation  
practices such as “Tell don’t ask”.

Just because instance\_variable\_get and instance\_variable\_set are  
there, kind of like a fire extinguisher behind a glass door, doesn’t  
mean that their use should be encouraged, or that magic hammers to  
break the glass without thinking about the consequences are a good  
idea.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 30, 2008, 5:21pm UTC](https://www.ruby-forum.com/t/instance-variable-access/133338/4 "2008-03-30T17:21:20Z")

</div>

On Sun, Mar 30, 2008 at 5:04 PM, Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Just because instance\_variable\_get and instance\_variable\_set are  
> there, kind of like a fire extinguisher behind a glass door, doesn’t  
> mean that their use should be encouraged, or that magic hammers to  
> break the glass without thinking about the consequences are a good  
> idea.  
> I see your point but disagree nevertheless, why should we poor  
> metaprogrammers or DSL implementers not give ourselves the tools, IOW  
> if one wants to abuse of Tom’s code one will abuse of the classical  
> ivar accessors instead.  
> But I agree with you in general about the usage of metaprogramming.  
> BTW Tom is doing his best for “Tell don’t ask” but at the metalevel.

Robert

> –  
> Rick DeNatale
> 
> My blog on Ruby  
> [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

–  
[http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

* * *

Whereof one cannot speak, thereof one must be silent.  
Ludwig Wittgenstein

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 31, 2008, 3:30am UTC](https://www.ruby-forum.com/t/instance-variable-access/133338/5 "2008-03-31T03:30:27Z")

</div>

Hi–

On Mar 30, 11:04 am, “Rick DeNatale” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Just because instance\_variable\_get and instance\_variable\_set are  
> there, kind of like a fire extinguisher behind a glass door, doesn’t  
> mean that their use should be encouraged, or that magic hammers to  
> break the glass without thinking about the consequences are a good  
> idea.

The intent is not to encourage meta-programming when meta-programming  
should not be used. But only to better facilitate it when it is used.  
In fact, a general tactic of Ruby is to use long names or  
**shadow\_methods** for such things as a form of discouragement  
(perhaps a silly practice but there it is nonetheless). What I propose  
here keeps in toe with that since it requires an additional decorative  
layer to gain access to the instance variables.

T.
