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.