Instance variable access

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.

On Sun, Mar 30, 2008 at 1:05 PM, Trans [email protected] 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/


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

On Sun, Mar 30, 2008 at 10:09 AM, Robert D. [email protected]
wrote:

On Sun, Mar 30, 2008 at 1:05 PM, Trans [email protected] 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/

On Sun, Mar 30, 2008 at 5:04 PM, Rick DeNatale [email protected]
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://ruby-smalltalk.blogspot.com/


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

Hi–

On Mar 30, 11:04 am, “Rick DeNatale” [email protected] 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.