From: Robert Klemme Date: 2009-10-13T23:45:21+09:00 Subject: Re: Class Level inheritable attributes - are we there yet? 2009/10/13 Dreamcat Four : > 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. This is a classical case I would resolve with instance methods that return constant values because the information is not needed at class level but at instance level. So we get class Centipide def mouths; 1 end def eyes; 5; end def body_segments; 5 end def legs; 10 end def run puts "opening my #{eyes} eyes and starting to move" legs.times do |i| puts "moving leg #{i}" end end end class SubCenti < Centipide def body_segments; 5 end def legs; 10 end end Strictly speaking the class does not have segments, legs etc. - only instances have. The scheme with instance methods can be kept even if you provide for individual (i.e. per object) values by providing a default via constant methods similar to those shown above. > 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. Btw, deep copy is usually used in the context of copying object graphs. If I understand you correctly you mean something else (inheriting values through hierarchies). > 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). Again, shallow copy seems to be a misnomer here. > 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: >> 2009/10/13 ara.t.howard : >> 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? But you can have duck typing! ;-) >> - 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. My understanding of the above is this. You have two use cases in mind: 1. Inheriting dynamic attribute values defining a proximity rule, i.e. when asked you get the closest attribute. 2. Constants which with the same proximity lookup rule as above only that values do not change after the initialization. > 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. Yes, although the syntax could be viewed as part of the solution. Before promoting something to the standard library I would also like to know how much use cases there are. In other words if (unlikely worst case) you and Ara would be the only once that have a need for this then I'd vote for not including in the std lib. Right now I have two issues: 1. I still have not seen a use case which would cry for a library solution which is not there yet (see above). (I still need to ponder the board example in your other email.) 2. It seems there are not many people wanting this (yet) - which might well be caused by the fact that I don't read every single posting to ruby-talk. I do have a feeling though that if there was massive demand for this we would see it in the std lib by now. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/