Newbie Question

It is not clear at all (to me) what you mean by 'inheriting variables'.
As Chad and myself pointed out, you seem to be suggesting that you
want to share access to some state but the exact scope of the sharing
isn't really clear. I've suggested a couple of ideas, and I understand
that they are not as simple as 'attr :foo', but I'm not sure if it is the
syntax or the semantics that is problematic for you.

Gary Wright

···

On Mar 1, 2007, at 6:50 PM, james.d.masters@gmail.com wrote:

Wouldn't it just be nice to have a way to inherit variables instead of
jumping through hoops? So that leads us back to my original question:
do later versions of Ruby plan on addressing this? I think that the
answer for now is "no" as I haven't heard anything to the contrary.

It seems like this is approaching the notions of delegation rather
than inheritance.

Some years ago there was a raging debate over delegation vs.
inheritance in the OO community. (Do a google search on oopsla
delegation inheritance).

Some languages unified instance variables with methods. Self did
this. Self had no explicit classes, objects have named slots which
contain values, some of which are executable. And these named slots
were resolved by walking up a chain of objects (rather than having a
superclass you delegate to another object).

Ruby actually uses somewhat similar mechanisms, but it separates
methods from instance variables, it puts the tables which are used to
find methods into a class rather than in the instance itself (even for
singleton methods which get put in singleton classes). Although Ruby
instance variables are implemented by name lookup in an instance
variable table owned by the instance, there's no instance chaining so
there's no place to search upwards for instance variables.

···

On 3/2/07, Brian Candler <B.Candler@pobox.com> wrote:

On Fri, Mar 02, 2007 at 08:10:10AM +0900, james.d.masters@gmail.com wrote:
> > Go back and look at my earlier post...
>
> OK, I did... and I also ran the code that you provided in the second
> example. I really do understand the concept of class instance
> variables. But I'm trying to show how they can be preset and have the
> preset values inherited.

Maybe this is where the confusion arises. Here you're talking about
inheritance of *values*, which implies the value from class A is *copied* to
class B. The trouble with that approach is, when exactly do you copy the
values? When class B is first created? But that assumes that class A has
already set its instance variable. If it hasn't, then there's nothing for
class B to copy.

That's why my suggestion was to set the value in the class's own instance
variable space only, and not copy it, but at the point when you *read* the
value, if you don't have it in your own instance variable space then walk
upwards.

--
Rick DeNatale

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

Thanks Rick and all who have added their thoughts into this
discussion. The more I think about it I can see that the behavior
that I was looking for would likely not be used as often as I first
thought. Here is a simplified example of what brought me to this
question in the first place. I have a CAD-related script that uses
quite a bit of inheritence. I had reference points as coordinates
that could be defined at a parent class or inherited class level; yet
not cross namespace with siblings. I use classes instead of instances
to store this data because multiple objects are created from these
classes and all objects would use the same reference points of the
class. Here is an example (using Brian's trick from his earlier
post):

class Canvas
  class << self
    def ref_pt(name, value=nil)
      @pts = {} if @pts.nil?
      if value.nil?
        # get value
        self.ancestors.each { |k|
          k.instance_eval { return @pts[name] if not @pts.nil? and
@pts.has_key? name }
        }
        nil
      else
        # set value
        @pts[name] = value
      end
    end
  end
end

class Canvas1 < Canvas
end

class Canvas1A < Canvas1
end

class Canvas2 < Canvas
end

# Set some reference points as an example
Canvas.ref_pt(:common_pt, [1.23, 2.34])
Canvas1.ref_pt(:sub1_pt, [3.45, 4.56])
Canvas1A.ref_pt(:sub1a_pt, [5.67, 6.78])
Canvas2.ref_pt(:sub2_pt, [7.89, 8.90])

# shortcut array to speed up output
klasses = [Canvas, Canvas1, Canvas1A, Canvas2]

# Show points common to descendents of Canvas
puts "Variable set at Canvas level (:common_pt):"
klasses.each {|k| puts "#{k}: #{k.ref_pt(:common_pt).inspect}"}
puts '-' * 78

# Show points common to descendents of Canvas1
puts "Variables set at Canvas1 level (:sub1_pt)"
klasses.each {|k| puts "#{k}: #{k.ref_pt(:sub1_pt).inspect}"}
puts '-' * 78

# Show points common to descendents of Canvas1A
puts "Variables set at Canvas1A level (:sub1a_pt)"
klasses.each {|k| puts "#{k}: #{k.ref_pt(:sub1a_pt).inspect}"}
puts '-' * 78

# Show points common to descendents of Canvas2
puts "Variables set at Canvas2 level (:sub2_pt)"
klasses.each {|k| puts "#{k}: #{k.ref_pt(:sub2_pt).inspect}"}

And the output for convenience:

Variable set at Canvas level (:common_pt):
Canvas: [1.23, 2.34]
Canvas1: [1.23, 2.34]
Canvas1A: [1.23, 2.34]
Canvas2: [1.23, 2.34]

···

On Mar 2, 10:57 am, "Rick DeNatale" <rick.denat...@gmail.com> wrote:

It seems like this is approaching the notions of delegation rather
than inheritance ... And these named slots were resolved by walking
up a chain of objects (rather than having a superclass you delegate
to another object) ...

------------------------------------------------------------------------------
Variables set at Canvas1 level (:sub1_pt)
Canvas: nil
Canvas1: [3.45, 4.56]
Canvas1A: [3.45, 4.56]
Canvas2: nil
------------------------------------------------------------------------------
Variables set at Canvas1A level (:sub1a_pt)
Canvas: nil
Canvas1: nil
Canvas1A: [5.67, 6.78]
Canvas2: nil
------------------------------------------------------------------------------
Variables set at Canvas2 level (:sub2_pt)
Canvas: nil
Canvas1: nil
Canvas1A: nil
Canvas2: [7.89, 8.9]

If this adds more confusion, then please disregard :). Otherwise,
thanks again for the input from everyone...