On Oct 7, 8:57 pm, "Austin Ziegler" <halosta... / gmail.com> wrote: > On 10/7/07, Trans <transf... / gmail.com> wrote: > > > On Oct 7, 10:42 am, "Pat Maddox" <perg... / gmail.com> wrote: > >> You misunderstand me. What looks painful to me is having the > >> behavior of a class tucked away behind 15 different modules, instead > >> of being right in the class where it belongs. > > I see. Well it's a trade-off. Would you prefer a class with 50 > > attributes or one that divides those into a few groups based on what > > they concern? For instance I have a Package class, it consists of > > General, Version, Content and Control components. I use that as a > > library reference object. However when I want to use it for creating > > distributable packages I mixin Distribution and Dependency modules. > > Personally? I'd prefer the former. If I was dumb enough to design > something that required 50 attributes. Let's pick on your example: > > class Package > class Description end > # Should be Package::Description > attr_accessor :description > > class Version; end > # Should be Package::Version > attr_accessor :version > > class Contents; end > # Should be Package::Contents > attr_accessor :contents > > class Controller; end > # Should be Package::Controller > attr_accessor :controller > > class Distributable < Package > class Distribution; end > attr_accessor :distribution > > class Dependency; end > # Probably should be specialized further so that it's a list of > # dependencies, so it should be attr_reader with a good initialize > # to fix this issue. > attr_accessor :dependencies > end > end > > There we go. It's now a properly composed object that doesn't mix in > multiple pieces of functionality into a flat access hierarchy. I now > have a Package::Version *class* to reuse elsewhere if I want, and it's a > full-on black box. I don't have any worries that Package::Version the > class will have any instance variables that conflict with another item > because I used a module. > > It took me all of thirty seconds to fix your design and make it > class-oriented rather than module-oriented. My objects are now more > usable as a whole and the overall interface substitution capabilities > are improved because now my Package class doesn't HAVE fifty attributes; > it's got FIVE. The Distributable package is properly specialized, too. > It might be possible to use a module to extend a package object into a > distributable package object rather than a subclass, but I'm not sure > that the design for that is a good one. > > Because each of my classes is smaller, my code is likely to be > significantly more robust, and I have functionality that I can > test independently of the whole Package class without trying to mix it > into something different. > > That's what I mean, Trans: your design approach for mixing in 50 > attributes or writing 50 attributes is bad. If you need that many, your > object is PROBABLY way too big. (Yes, there are times when such things > are necessary; they're extremely uncommon, though.) Fantastic jobs Austin. Now initialize the class from a YAML file for me. Did I mention the file spec looks like this: --- package: version: created: homepage: devsite: authors: description: libpaths: etc... It has some 35+ possible entires and some of those have aliases besides (because I like giving my users some flexibility). Plus it should be extensible because other utilities (like the distributable packaging tool) will need additional information. Come on, show the dumb-dumb how it's *properly* done. T.