T
Trans
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,
hone
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
=> {
hone=>"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.
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,
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
=> {
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.