Class Level inheritable attributes - are we there yet?

Hi,
I'm having trouble understanding why this isn't available from the Ruby core?
Does core not provide an alternative / satisfactory implementation of this?

# clia.rb - Class Level Inheritable Attributes

module ClassLevelInheritableAttributes
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def inheritable_attributes(*args)
      @inheritable_attributes ||= [:inheritable_attributes]
      @inheritable_attributes += args
      args.each do |arg|
        class_eval %(
          class << self; attr_accessor :#{arg} end
        )
      end
      @inheritable_attributes
    end

    def inherited(subclass)
      @inheritable_attributes.each do |inheritable_attribute|
        instance_var = "@#{inheritable_attribute}"
        subclass.instance_variable_set(instance_var,
instance_variable_get(instance_var))
      end
    end
  end
end

class Polygon
  include ClassLevelInheritableAttributes
  inheritable_attributes :sides
  @sides = 8
end

puts Polygon.sides # => 8

class Octogon < Polygon; end

puts Polygon.sides # => 8
puts Octogon.sides # => 8

Ref: http://railstips.org/2006/11/18/class-and-instance-variables-in-ruby

Its rather difficult to believe we must in each case define / require
our own custom module. Please note - i'm not complaining here. I just
want to know whether the above example is "the best solution in use"
for 1.8... 1.9....

Best regards,

dreamcat4
dreamcat4@gmail.com

Hi --

Hi,
I'm having trouble understanding why this isn't available from the Ruby core?
Does core not provide an alternative / satisfactory implementation of this?

# clia.rb - Class Level Inheritable Attributes

module ClassLevelInheritableAttributes
def self.included(base)
   base.extend(ClassMethods)
end

module ClassMethods
   def inheritable_attributes(*args)
     @inheritable_attributes ||= [:inheritable_attributes]
     @inheritable_attributes += args
     args.each do |arg|
       class_eval %(
         class << self; attr_accessor :#{arg} end
       )
     end
     @inheritable_attributes
   end

   def inherited(subclass)
     @inheritable_attributes.each do |inheritable_attribute|
       instance_var = "@#{inheritable_attribute}"
       subclass.instance_variable_set(instance_var,
instance_variable_get(instance_var))
     end
   end
end
end

class Polygon
include ClassLevelInheritableAttributes
inheritable_attributes :sides
@sides = 8
end

puts Polygon.sides # => 8

class Octogon < Polygon; end

puts Polygon.sides # => 8
puts Octogon.sides # => 8

Ref: Class and Instance Variables In Ruby // RailsTips by John Nunemaker

Its rather difficult to believe we must in each case define / require
our own custom module. Please note - i'm not complaining here. I just
want to know whether the above example is "the best solution in use"
for 1.8... 1.9....

I would probably write it a little differently, maybe like this:

module ClassLevelInheritableAttributes
   def inheritable_attributes(*args)
     (class << self; self; end).class_eval do
       attr_accessor *args
     end

     @inheritable_attributes ||=
     @inheritable_attributes.concat(args)
   end

   def inherited(subclass)
     @inheritable_attributes.each do |attr|
       subclass.send("#{attr}=", send(attr))
     end
     super
   end
end

class Whatever
   extend ClassLevelInheritableAttributes
end

etc. I'm not sure it's a common enough idiom to be worthy of a new
language construct, though. I love the fact that you can make what are
essentially language-level-like constructs from a few lines of code in
Ruby. I think that very, very few of them should be promoted to the
actual language.

David

···

On Sun, 11 Oct 2009, dreamcat four wrote:

--
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)

One alternative:

  http://rubyworks.github.com/inheritor/

···

On Oct 10, 2:02 pm, dreamcat four <dreamc...@gmail.com> wrote:

Hi,
I'm having trouble understanding why this isn't available from the Ruby core?
Does core not provide an alternative / satisfactory implementation of this?

Its rather difficult to believe we must in each case define / require
our own custom module. Please note - i'm not complaining here. I just
want to know whether the above example is "the best solution in use"
for 1.8... 1.9....

you certainly aren't complaining and i must say that i'm a little
disappointed in the responses you are getting from people.

let me start out by saying that it is a *fact* that inheritable class
attributes are both useful and re-invented over and over. do a search
on github, rubyforge, raa, google, and this mailing list and you will
find hundreds of examples. github alone has 237 pages of results for
this search in many languages. i'd also point out that there are
really two kinds of rubyists: those who write code for themselves and
those who write code for others. if you systematically do searches
(on the same sources as above) for the people are against permutations
of class state vs. people are for it you will see a trend: people who
write lots of libraries (especially 'dsl-y' libraries) are in favor
of, and make heavy us of, class state of all kinds including
inheritable state - those who are against it are mainly writing their
own code and using other people's libraries. the irony is that *most*
of the popular ruby libraries make use of inheritable class state:
just a short list

  . merb
  . ramaze
  . sqlite-ruby
  . main
  . couchrest
  . rubyigen
  . action_mailer
  . active_controller
  . active_record
  . extlib
  . facets
  . actionwebservice
  . active_support
  . zen test
  . fattr
  . etc...

so, if you like any of those libraries and what they have to offer,
you like class inheritable state being managed for you. in addition
i'd point out that anyone who likes esoteric concepts like 'method
dispatch' or 'constant lookup' also likes auto-magically maintained
class state. honestly it's tiresome to see this idea still being
debated on ruby-talk with buggy code and claims that rolling your own
inheritance is easy (it isn't - trust me - at least not in the general
case). therefore i'd for one, as author of dozens of libraries which
have rolled their own class var inheritance, like to offer my support
of your plea: there absolutely should be a 'standard' method of doing
this. i don't know if that means being in core or that it should be a
library (possibly distributed with core), but you are quite correct in
observing that one has to be careful mixing methods with common names
like 'inheritable' into Object etc. a common, simple, and reusable
library would be a great help to many library writers and people that
claim that it wouldn't be obviously aren't writing a lot of libraries
- at least not certain types of libraries.

i'll leave you with my current favorite method of rolling class
inheritable attributes:

the fattr lib, avail as gem and at http://github.com/ahoward/fattr\.
btw, anyone that thinks this is *easy* stuff should complete

  Ruby Quiz - metakoans.rb (#67)

although some of the complete answers are terse they are *not*
simple. the fattr code is based on the best answers.

cfp:~/src/git/fattr > cat a.rb
require 'rubygems'
require 'fattr'

class A
  class << A
    fattr(:x, :inheritable => true){ 42 }
  end
end

class B < A; end

class C < B; end

p C.x
p B.x
p A.x
puts

B.x = 42.0

p C.x
p B.x
p A.x
puts

C.x! # force re-initialization from parent(s)

p C.x
p B.x
p A.x
puts

class K
end
class L < K
end
module M
  fattr(:x, :inheritable => true){ 42 }
end
K.extend(M)

p L.x

cfp:~/src/git/fattr > ruby a.rb
42
42
42

42
42.0
42

42.0
42.0
42

42

regards.

The problem with class variables in Ruby, is that a class variable is
the same object across all subclasses of a class. This is in my
opinion almost never what you’d want. More probable is that you’d want
the individual class instance to have an accessor. (Remember classes
are objects in Ruby).

dreamcat4
dreamcat4@gmail.com

I was going to post a pointer to fattr but now I don't have to.

I've used fattr for a few private projects and have found it quite
useful.

Gary Wright

···

On Oct 12, 2009, at 1:47 PM, ara.t.howard wrote:

i'll leave you with my current favorite method of rolling class
inheritable attributes:

the fattr lib, avail as gem and at http://github.com/ahoward/fattr\.
btw, anyone that thinks this is *easy* stuff should complete

I'm puzzled by the divisive tone of this. I think we're all on the
same side -- not necessarily of every topic that gets discussed here,
but of the basic principle that we're all trying to help each other.

In any case -- I'm not "against" class state. (I'm not even sure what
that would mean.) I am conservative about use-cases, even important
ones, making their way into the language as language-level constructs.
That's what I've emphasized in this thread.

I think too that you're conflating two distinct sub-issues: the
creation of language-level constructs, and the phenomenon of rewriting
the same code over and over. Obviously the latter is a bad idea, and
no one in this thread is suggesting otherwise. If I say that Ruby can
sustain a lot of quasi-language-feature-ish add-ons without having
them be put in the language, that does not imply that these should be
typed out by hand anew every time they're going to be used.

David

···

On Tue, 13 Oct 2009, ara.t.howard wrote:

Its rather difficult to believe we must in each case define / require
our own custom module. Please note - i'm not complaining here. I just
want to know whether the above example is "the best solution in use"
for 1.8... 1.9....

you certainly aren't complaining and i must say that i'm a little
disappointed in the responses you are getting from people.

let me start out by saying that it is a *fact* that inheritable class
attributes are both useful and re-invented over and over. do a search
on github, rubyforge, raa, google, and this mailing list and you will
find hundreds of examples. github alone has 237 pages of results for
this search in many languages. i'd also point out that there are
really two kinds of rubyists: those who write code for themselves and
those who write code for others. if you systematically do searches
(on the same sources as above) for the people are against permutations
of class state vs. people are for it you will see a trend: people who
write lots of libraries (especially 'dsl-y' libraries) are in favor
of, and make heavy us of, class state of all kinds including
inheritable state - those who are against it are mainly writing their
own code and using other people's libraries. the irony is that *most*
of the popular ruby libraries make use of inheritable class state:
just a short list

--
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)

Ah,
I seems that ActiveSupport’s class_inheritable_accessor, seems to do
the same. class_inheritable_accessor (or what I showed) uses instance
variables (@foo) at the Class instance level. These variables are not
shared across all subclasses.

require 'activesupport'

class Base
  class_inheritable_accessor :value
  self.value = '123'
end

class Derived < Base; end
class Derived2 < Base; end

Derived.value #=> '123'
Derived.value = 'abc'
Base.value #=> '123'
Derived2.value #=> '123

It becomes a problem when using a mixture of libraries which all
define methods on Class, Kernel or Object. Obviously namespace clashes
can happen, (and indeed they have already).

Best regards,

dreamcat4
dreamcat4@gmail.com

Hi --

···

On Sun, 11 Oct 2009, dreamcat four wrote:

The problem with class variables in Ruby, is that a class variable is
the same object across all subclasses of a class. This is in my
opinion almost never what you’d want. More probable is that you’d want
the individual class instance to have an accessor. (Remember classes
are objects in Ruby).

Oh, there are lots of problems with class variables :slight_smile: I didn't
mention them. Was there something in my post that made it sound like I
was suggesting class variables?

David

--
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)

The problem with class variables in Ruby, is that a class variable is
the same object across all subclasses of a class. This is in my
opinion almost never what you’d want. More probable is that you’d want
the individual class instance to have an accessor. (Remember classes
are objects in Ruby).

Class variables are one of the few features I would elect for completely throwing out of the language since they are complex, can be error prone (initialization order matters) and use cases are rare (if existent at all).

Having said that I am not sure that you actually need a language construct when you can do this:

class A
   class <<self
     def foo
       @foo || superclass.foo
     end
   end

   @foo = 1
end

class B < A
end

class C < A
   @foo = 2
end

[A,B,C].each do |cl|
   printf "%-2s %p\n", cl, cl.foo
end

robert@fussel:/tmp$ ruby1.9 cl.rb
A 1
B 1
C 2

And I completely agree to what David said:

I'm not sure it's a common enough idiom to be worthy of a new
language construct, though. I love the fact that you can make what are
essentially language-level-like constructs from a few lines of code in
Ruby. I think that very, very few of them should be promoted to the
actual language.

Kind regards

  robert

···

On 10/10/2009 08:59 PM, dreamcat four wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

??

the OP simply asked why a useful idiom wasn't supported in core, which
includes it's libraries. he very clearly asked for "the best solution
in use." the subsequent posts responded as to why we shouldn't change
the language, which was never suggested, and a critique of the of the
example code, which was never asked for.

the implication was quite clear: that there isn't a best practice and
that solution should be typed out by hand since "you can make what are
essentially language-level-like constructs from a few lines of code in
Ruby"

this really isn't true in this case and it is precisely at the center
of the OP's dilemma: how to best approach having inheritable class
state without writing subtle and error prone code.

unless a concrete answer regarding which libraries to use or a tested,
proven, and complete implementation is given i think the the OP isn't
being given a fair answer to a fair question which was not: 'what do
people think about this', but was instead: 'how, exactly, should i do
this and follow best practices.'

honestly, if you read the thread start to finish, i do not think the
OP's question was given due consideration and i also think his intent
was co-opted into a request for a language change.

i'm simply requesting that the group focus on a good, concrete,
solution for a hard problem instead of simply telling people that the
issue is so easy that it's not even worth solving.

i'd love to see some thinking about the various attempts at a complete
solution. the OP has already noted that the most common are flawed
for even moderately complex use cases, maybe the collective can narrow
in on, and even improve upon, the better ones. i've personally spent
a week or two trying to solve this problem in the general case and
have found it profoundly slippery to get right. i've already posted
my attempt at a minimal but complete solution (fattr) but would love
to hear some legitimate and thoughtful analysis of other approaches.
if a particular solution could gain some momentum as being best
practice it would a big help for the next generation of ruby
programmers - so much so that an RCR, or whatever they are called
these days, might really be in order.

regards.

···

On Mon, Oct 12, 2009 at 17:48, David A. Black <dblack@rubypal.com> wrote:

that does not imply that these should be
typed out by hand anew every time they're going to be used.

--
-a
--
be kind whenever possible... it is always possible - h.h. the 14th dalai lama

No, its just a generally accepted problem with the ruby language.

dreamcat4
dreamcat4@gmail.com

···

On Sat, Oct 10, 2009 at 8:10 PM, David A. Black <dblack@rubypal.com> wrote:

On Sun, 11 Oct 2009, dreamcat four wrote:

The problem with class variables in Ruby, is that a class variable is
the same object across all subclasses of a class. This is in my
opinion almost never what you’d want. More probable is that you’d want
the individual class instance to have an accessor. (Remember classes
are objects in Ruby).

Oh, there are lots of problems with class variables :slight_smile: I didn't
mention them. Was there something in my post that made it sound like I
was suggesting class variables?

It shouldn't be mandated to re-invent the wheel in any programming
language, even if its fun style / fun to write. Here is why Robert:
because you would have just put 2 bugs into your code.

1) It breaks when you want to set foo = nil in a subclass.
2) Not having an accessor definition will break other code.

puts A.instance_variables.inspect
=> ["@foo"]
puts B.instance_variables.inspect
=>
puts C.instance_variables.inspect
=> ["@foo"]

Most people would try / expect to fix by putting attr_accessor :foo at
top class A. It simply doesn't work and the regular accessor is not
inherited. Because in Ruby the Class is instantiated as an instance of
object. You could probably imagine a little imaginary OO professor
tugging at your clothes and saying 'tut tut, such a shame' or
something. And you might argue back that the point was that these
aren't bugs if you understand the limitations etc, etc. Just like
being back at school eh? But i can assure you when any real programmer
in the real world comes along to use your classes and / or modify your
code, these holes are eventually surface as real breakages / bugs.

Heres my own top 3 recommendations:

* Give up / don't use any. Avoid if possible.

* Use the activeresource class inheritable accessor. I guess that's
not so much of a stretch if you are already depending upon
activeresource for other things.

* Request a real language implementation in ruby core because class is
an object. It would be entirely a matter for the ruby development team
to decide whether they would want to implement it, and/or how. I'm
very surprised no-one has asked for this on 1.9 line, or to change the
existing @@ behaviour since are changed the block level variable
scoping and many other things.

dreamcat4
dreamcat4@gmail.com

···

On Sun, Oct 11, 2009 at 6:55 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

Having said that I am not sure that you actually need a language construct
when you can do this:

class A
class <<self
def foo
@foo || superclass.foo
end
end

i'm simply requesting that the group focus on a good, concrete,
solution for a hard problem instead of simply telling people that the
issue is so easy that it's not even worth solving.

Ara, I don't agree to everything you write above especially since - as
far as I can see - "the problem" was never stated precisely. But
let's not follow that chain of discussion.

i'd love to see some thinking about the various attempts at a complete
solution. the OP has already noted that the most common are flawed
for even moderately complex use cases, maybe the collective can narrow
in on, and even improve upon, the better ones. i've personally spent
a week or two trying to solve this problem in the general case and
have found it profoundly slippery to get right. i've already posted
my attempt at a minimal but complete solution (fattr) but would love
to hear some legitimate and thoughtful analysis of other approaches.
if a particular solution could gain some momentum as being best
practice it would a big help for the next generation of ruby
programmers - so much so that an RCR, or whatever they are called
these days, might really be in order.

OK, let's start over. For that first I would like to understand what
the problem actually is that needs to be solved here. There are many
aspects to this and I would love to see something like a requirements
list which particularly states the problem. Questions I have in mind:

- Do those attributes need to change or are they set once (quasi /
real constant)?
- If a subclass inherits a value from the superclass is it supposed to
inherit changes to the value as well?
- What happens if a super class has its attribute unset? You might
want to retain all sub class values - or not.
- What happens if a super class has its attribute set? You might want
to override all sub class values at this moment.
- Must modules along the inheritance chain get their own values or is
the feature in question restricted to class instances? (Note, it's
almost impossible to include modules here because they may be part of
multiple inheritance chains.)
- Is the feature expected to work with different combinations to the
questions above.

Concluding from the complexity you attribute to the problem I assume
you can provide more of those guiding questions. Once we have common
understanding what the problem is we can start to think about
solutions.

Kind regards

robert

···

2009/10/13 ara.t.howard <ara.t.howard@gmail.com>:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

that does not imply that these should be
typed out by hand anew every time they're going to be used.

??

I was responding to your comments about this being re-invented
repeatedly, which is not what I had been recommending. I wanted to
make that clear.

the OP simply asked why a useful idiom wasn't supported in core, which
includes it's libraries. he very clearly asked for "the best solution
in use." the subsequent posts responded as to why we shouldn't change
the language, which was never suggested, and a critique of the of the
example code, which was never asked for.

the implication was quite clear: that there isn't a best practice and
that solution should be typed out by hand since "you can make what are
essentially language-level-like constructs from a few lines of code in
Ruby"

But *not* typed out by hand anew every time they're going to be used.
The operative word in my statement was "anew".

honestly, if you read the thread start to finish, i do not think the
OP's question was given due consideration and i also think his intent
was co-opted into a request for a language change.

The beginning of the first post is:

I'm having trouble understanding why this isn't available from the
Ruby core? Does core not provide an alternative / satisfactory
implementation of this?

I'm a bit puzzled by what you're saying. It would never occur to me to
"co-opt" a question. But let's move on.

i'm simply requesting that the group focus on a good, concrete,
solution for a hard problem instead of simply telling people that the
issue is so easy that it's not even worth solving.

i'd love to see some thinking about the various attempts at a complete
solution. the OP has already noted that the most common are flawed
for even moderately complex use cases, maybe the collective can narrow
in on, and even improve upon, the better ones. i've personally spent
a week or two trying to solve this problem in the general case and
have found it profoundly slippery to get right. i've already posted
my attempt at a minimal but complete solution (fattr) but would love
to hear some legitimate and thoughtful analysis of other approaches.
if a particular solution could gain some momentum as being best
practice it would a big help for the next generation of ruby
programmers - so much so that an RCR, or whatever they are called
these days, might really be in order.

Coming at it from the other angle, I'd be interested in seeing more
use cases -- not that there aren't some around, but most of the ones
I've seen seem to lend themselves to relatively simple solutions. That
probably means I haven't looked at the right ones....

David

···

On Tue, 13 Oct 2009, ara.t.howard wrote:

On Mon, Oct 12, 2009 at 17:48, David A. Black <dblack@rubypal.com> wrote:

--
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)

Hi --

Having said that I am not sure that you actually need a language construct
when you can do this:

class A
class <<self
def foo
@foo || superclass.foo
end
end

It shouldn't be mandated to re-invent the wheel in any programming
language, even if its fun style / fun to write. Here is why Robert:
because you would have just put 2 bugs into your code.

But using the available techniques in a language to put together
something higher level is not "re-inventing the wheel" (unless you do
it repeatedly). The language cannot be expected to incorporate an
abstract construct for every use case.

1) It breaks when you want to set foo = nil in a subclass.

You can fix this with a defined? test.

2) Not having an accessor definition will break other code.

puts A.instance_variables.inspect
=> ["@foo"]
puts B.instance_variables.inspect
=>
puts C.instance_variables.inspect
=> ["@foo"]

That's not broken; it just means that what Robert is doing isn't
identical to what, say, attr_accessor does. You could modify Robert's
code to assign to the instance variable the first time around rather
than just examining it, or something like that.

Most people would try / expect to fix by putting attr_accessor :foo at
top class A. It simply doesn't work and the regular accessor is not
inherited.

It is inherited; that is, given this:

   class A
     attr_accessor :x
   end

   class B < A
   end

instances of B will have an x attribute. But, as you say, this isn't
relevant to the class instance, and if people try to do it in order to
address class-level state, they just haven't yet learned enough about
the Ruby object model to know that things don't work that way. So
they'll learn :slight_smile:

Because in Ruby the Class is instantiated as an instance of
object. You could probably imagine a little imaginary OO professor

(A class is actually an instance of Class.)

tugging at your clothes and saying 'tut tut, such a shame' or
something. And you might argue back that the point was that these
aren't bugs if you understand the limitations etc, etc. Just like
being back at school eh? But i can assure you when any real programmer
in the real world comes along to use your classes and / or modify your
code, these holes are eventually surface as real breakages / bugs.

I don't know whether Robert regards them as bugs or not, but I think
the main point is that there a whole world of this stuff you can do
trivially in Ruby. Besides, the examples we send back and forth on
ruby-talk aren't necessarily fully field-tested; that's not really the
point of the forum :slight_smile:

Heres my own top 3 recommendations:

* Give up / don't use any. Avoid if possible.

* Use the activeresource class inheritable accessor. I guess that's
not so much of a stretch if you are already depending upon
activeresource for other things.

* Request a real language implementation in ruby core because class is
an object. It would be entirely a matter for the ruby development team
to decide whether they would want to implement it, and/or how. I'm
very surprised no-one has asked for this on 1.9 line, or to change the
existing @@ behaviour since are changed the block level variable
scoping and many other things.

I'm still not seeing why it's so important that it be addressed in the
core. Of course I'd be glad to see @@ changed to something more useful
(Robert and I have been among the most vocal critics of class
variables over the years :slight_smile: but I don't want to see classes
special-cased when it comes to how they maintain their own state.
They're objects, and objects maintain state with instance variables,
which classes can easily do.

I've often said that "because classes are also objects" is the answer
to 75% of all questions about Ruby :slight_smile: That's actually why I don't
like extra special cases for classes. Once people understand that
they're objects, and let go of trying to view them as entirely
special, many things fall into place and the language makes more
sense.

David

···

On Mon, 12 Oct 2009, dreamcat four wrote:

On Sun, Oct 11, 2009 at 6:55 PM, Robert Klemme > <shortcutter@googlemail.com> wrote:

--
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)

.

2) Not having an accessor definition will break other code.

puts A.instance_variables.inspect
=> ["@foo"]
puts B.instance_variables.inspect
=>
puts C.instance_variables.inspect
=> ["@foo"]

attribute accessors don't cause instance variables to exist until the
setter (or some other method) initializes the instance variable:

class A
  attr_accessor :bar
  class << self
    attr_accessor :foo
  end
end

A.instance_variables # =>
a = A.new
a.instance_variables # =>

A.foo = 42
a.bar = 39

A.instance_variables # => ["@foo"]
a.instance_variables # => ["@bar"]

···

On Sun, Oct 11, 2009 at 3:34 PM, dreamcat four <dreamcat4@gmail.com> wrote:

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Having said that I am not sure that you actually need a language construct
when you can do this:

class A
class <<self
def foo
@foo || superclass.foo
end
end

It shouldn't be mandated to re-invent the wheel in any programming
language, even if its fun style / fun to write.

Which wheel did I reinvent?

Here is why Robert:
because you would have just put 2 bugs into your code.

1) It breaks when you want to set foo = nil in a subclass.
2) Not having an accessor definition will break other code.

puts A.instance_variables.inspect
=> ["@foo"]
puts B.instance_variables.inspect
=>
puts C.instance_variables.inspect
=> ["@foo"]

David has said everything there is to say about this. I modeled the
quick hack based on your original example which obviously needed to
maintain constant values at class level which would have been better
done like this:

11:07:12 desktop$ ruby19 cl.rb
A 1
B 1
C 2
11:07:24 desktop$ cat cl.rb
class A
  Foo = 1
end

class B < A
end

class C < A
  Foo = 2
end

[A,B,C].each do |cl|
printf "%-2s %p\n", cl, cl::Foo
end

If any, that would have been the "bug" in my approach. The code was
merely meant to demonstrate what can be done with a few lines of code
and that accessors (in fact all methods) defined for class instances
are inherited to subclasses.

Regards

robert

···

2009/10/11 dreamcat four <dreamcat4@gmail.com>:

On Sun, Oct 11, 2009 at 6:55 PM, Robert Klemme > <shortcutter@googlemail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Closer to what you want?

  class A
    def self.foo
      instance_variable_defined?("@foo") ? @foo : foo!
    end
    def self.foo!
      @foo = ancestors[1].foo if ancestors[1].respond_to?(:foo)
    end
    def self.foo=(x)
      @foo = x
    end
  end

Hi,
Before answering to Roberts specific questions, as the OP i'd like to
show the 'common sense' analogy from an outsiders perspective. This
analogy is of real-life taxonomy, and real darwinian evolution. Its sort
of 'how nature would do it'.

So a class is the species of animal.
An instance object is an individual animal that has been born, and is
living.

The sub-species (subclass) will inherit everything and permutate /
mutate the ancestor class.
An object instance can inherit all of the same. The difference is that a
species doesn't individually live many lives, it is 'a model instance'.
Wheras an object instance is free to lead any kind of a life, and there
may be many permutations of such.

The species are in evolution are generally minimal. (you only get new
ones when they are peoperly justified). There can be many objects, but
comparatively few species.

One species of centipide has 5 body segments and 10 legs
All instances of that species also has 5 body segments and 10 legs
They also have common behaviours (methods) such as running, twisting,
etc.

A new sub-species (subclass) is formed which has [6 seg, 12 legs]. But
it still has 5 eyes, 1 mouth, and so on. These are inherited values. The
new species can't correctly execute its inherited methods {run and
twist} if its body mechanism (when derived) always ever inherits a
default number of 0 arms, 0 legs, 0 body segments, and 0 everything
else.

1) So above is the 'common sense' paradigm. (actually i originally was
asking around for). So clearly meaning its requiring deep-copy. But
because we are talking about classes and not object then there should be
much fewer of declared in your program.

2) To share same attribute amongst classes (with rubys default shallow
copy) are generally helpful for certain global constant etc in a library
environment. (myself didn't ask for that but its clearly both variation
are needed).

3) When in ruby we instantiate an object, we don't always want to copy
these same attributes above (1 and 2) into the instance. (whether or not
they are type 1 or 2 doesn't matter). Reason: not want to deep-copy
excessively because we can have many instance object (which may or may
not use the class attribute). For example, think of the lazy centipede.
It wants to {twist and wriggle}, but can't be bothered to run, so it
doesn't hardly ever use its legs. So if we chopped the legs off, it
wouldn't matter for the most part.

Robert Klemme wrote:

OK, let's start over. For that first I would like to understand what
the problem actually is that needs to be solved here. There are many
aspects to this and I would love to see something like a requirements
list which particularly states the problem. Questions I have in mind:

- Do those attributes need to change or are they set once (quasi /
real constant)?

Yes, they need to be able to change and be any regular ruby object.
As per case 1)

- If a subclass inherits a value from the superclass is it supposed to
inherit changes to the value as well?

No for 1), yes for 2)

- What happens if a super class has its attribute unset? You might
want to retain all sub class values - or not.

Thats the same answer as the previous question.

- What happens if a super class has its attribute set? You might want
to override all sub class values at this moment.

Thats also the same answer as per the previous question.
Or i dont understand these questions.

- Must modules along the inheritance chain get their own values or is
the feature in question restricted to class instances? (Note, it's
almost impossible to include modules here because they may be part of
multiple inheritance chains.)

We don't want any polymorphic behaviour because it doesn't fit right
with natural evolution. In nature you can't cross a horse species with a
duck species to have a flying horse eh?

- Is the feature expected to work with different combinations to the
questions above.

Yes.
Its important to cover the fewest number of cases, and ensure a clear
differentiation between them. Im not 100% sure that fattr.rb syntax is
the best / most readable.

And also before we implement a solution, i hope also we can work out a
good clear syntax and do good example usages beforehand. Find the best
(to the end user) presentation so to show clearly and differentiate
between them. Otherwise it could be very unfriendly / confusing.

Options
* Whether it be a special character(like@), a special symbol (:sym),
* Wrapped in class << self (or not)
* Some accessor definition with argument
* Or some opt-in list, where must reference / redeclare attribute a
second time.
* any other diy DSL syntax, as long as it has merit

Best regards,

dreamcat4
dreamcat4@gmail.com

···

2009/10/13 ara.t.howard <ara.t.howard@gmail.com>:

--
Posted via http://www.ruby-forum.com/\.