Personally I would just have the builder in _orm_table figure this all out? or add an instance level 'orm_table' attribute so that I could vary it on a per-instance basis if the need ever arose.




Thanks, Stevan. My intent was to use class data for class methods (where you don't intend to have an instance). Your response made me wonder. Should one really have class methods? I am caught up in Rose::DB::Object's argument that if $product should exhibit the behaviors expected of a product record, $product->list is inappropriate. They go as far as to create a separate namespace for multi-object queries. So it's ok to say $product(name => 'kate'); $product->save; You have to say Product::Manager->get_products(name => 'kate') when you want to search.

Now that I am looking at it more closely, I am realizing that perhaps, it's this decision that's having me just through hoops in the first place! I am disliking the idea of needing to know the Product::Manager namespace and writing code to avoid it. Modifying Rose::DB::Object to drop this non-oo approach will make everything cleaner.

So there, Dave.  You win!  ;-)

---

Furthermore, I realized, I was wrong about the way MooseX::ClassAttribute works. My idea was that class data should be inherited (or applied from a role) just like regular methods and attributes. Turns out, this is not quite true. (I even wonder of this is the intended behavior!)

Instead, the implementation below will encounter all kinds of problems.

1. If classdata is in a Role, a weird error occurs: Moose complains that the builder is not supported by the child class (the one that gets the role applied). It probably has something to do with the order of parsing things. 2. If classdata is in a base class, then the builder, though inherited correctly, will receive the parent's class name as a class variable.

    e.g.

   Model::Account->orm_class(); #leads us into the builder

   sub _orm_class{
my $class = shift; warn $class; #prints Model instead of Model::Account
   }

 And hilarity ensues.

I am guessing, class data is supposed to be associated with the class that declares it and is not really inherited. They mentioned something about that in the docs, but I guess I didn't understand the implications. :-)


I think of class data as complex constants. For example, say, I have a Model layer, which aggregates ORM table objects. I might have something like this:

use constant orm_class_name =>'Table::Account';
has table (..., builder => '_orm_table');

...
sub _orm_table{
        shift->orm_class_name->new();
}
sub class_method_from_orm{
     shift->orm_class_name->method();
}

---

Now it is sensible for me to compute the orm_class_name based on the current package name - and a builder is the elegant way to do it (and I have to admit, builders are just plain pretty!)

class_has orm_class => (..., builder => '_orm_class', ...other fancy stuff possible...);

--
the rest of the code is unchanged - the class data is really little more than a very pretty constant. OK, so bottom line is, I am twitching because Dave Rolsky says, I am a Bad Person, and seeing as he's been right about everything else thus far, I'd like to see whether my argument makes sense, or if there is a better way to do it.



Reply via email to