Beefy Boxes and Bandwidth Generously Provided by pair Networks RobOMonk
Just another Perl shrine
 
PerlMonks  

Moose: What about "class" attributes?

by John M. Dlugosz (Monsignor)
on Apr 30, 2011 at 08:37 UTC ( #902153=perlquestion: print w/ replies, xml ) Need Help??
John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

I was under the impression that Moose did not have "class attributes", by which I mean a slot that is associated with all instances of a type rather than being per-instance. In C++ this would be a static member. In Smalltalk I think it's called a class variable.

I looked at Moose Manual Attributes to be sure, and it states, "An attribute is a property that every member of a class has."

Why the double-take? Because I see MooseX::Traits adds an attribute to the class called _trait_namespace whose value is used when you write:

my $class = Class->with_traits('Role')->new( foo => 42 );
How can Class->with_traits use a value found in a property of some specific instance of Class when it is not called on any instance? It sure looks like it must be a class variable!

The instructions on overriding the value of _trait_namespace does not show anything different. So what's going on here?

I want to do something similar, and have a value that is used by some class method (like new) and can be changed by a derived class. This looks like the accessor is a virtual class method (something C++ doesn't have).

In Smalltalk, class slots and virtual class methods are simply normal slots and methods on the metaclass instance (the class object itself). So it makes sense that Moose should accommodate such a thing as it uses the same architecture.

Looking at the source of MooseX::Traits, I see a perfectly ordinary has in a role. However, it is 'bare', so there is no getter and nothing else that would make it usable. Eventually, there is a call to

my $namespace = $class->meta->find_attribute_by_name('_trait_namespace +'); ... $namespace->default ...
So, I guess it's a hack. The slot is never used in an instance, and the default is accessed without any instance being populated with it. (Edit: Worse, I see that if the default is a sub ref, it is called with no arguments at all. The default sub is documented as being called as a method on the object. )

The use of such a thing is testimony that "class variables" and "class methods" are indeed wanted!

Comment on Moose: What about "class" attributes?
Select or Download Code
Re: Moose: What about "class" attributes?
by Khen1950fx (Canon) on Apr 30, 2011 at 09:23 UTC
      A class has zero or more attributes.
      So?

      It doesn't say anything about class-level attributes. I'm pretty sure that class methods as supported by Perl's normal dispatch are virtual, though, and that document doesn't say anything other than "Any subroutine you define in your class is a method."

Re: Moose: What about "class" attributes?
by lamprecht (Friar) on Apr 30, 2011 at 23:22 UTC
Re: Moose: What about "class" attributes?
by stvn (Monsignor) on May 01, 2011 at 02:16 UTC

    Moose has no base support for class attributes, and never will, mostly because I think they are a bad idea. That is not to say that I don't like static class data, I think that is fine and can easily be handled by using package level variables and "static" methods. But the idea of inheritable class attributes just make me cringe, but fortunately for those who disagree with me, Dave Rolsky has written MooseX::ClassAttribute which does an excellent job at providing this type of functionality.

    -stvn
      But the idea of inheritable class attributes just make me cringe
      So why does MooseX::Traits (which has your name on it) use hacks to achieve exactly that effect? The configuration of trait_namespace will inherit. If you don't like that, why not just use a simple package variable in the package of the object's original created type?

      I suppose someone else maintained it and added that bit... but how would you (or how did you originally) do it, in keeping with your stated design philosophy?

        So why does MooseX::Traits (which has your name on it) use hacks to achieve exactly that effect?

        This is the fun part about Open Source, just cause my name is on it doesn't mean I have done anything other then contribute some part of it and I am no way responsible for the contents ;)

        The configuration of trait_namespace will inherit. If you don't like that, why not just use a simple package variable in the package of the object's original created type?

        Well, in this case, inheritability is nice, but the goal here is more configurability of subclasses without altering the core MooseX::Traits itself (which would have global effects, which are bad bad bad).

        I suppose someone else maintained it and added that bit... but how would you (or how did you originally) do it, in keeping with your stated design philosophy?

        I am pretty sure jrockway wrote that part, it is not how I would approach it but this solution is not all that bad (I have seen worse). Keep in mind too that was also written quite a while ago, today one would accomplish this type of thing by making MooseX::Traits into a parameterized role using MooseX::Role::Parameterized.

        -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://902153]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (13)
As of 2014-04-17 20:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (454 votes), past polls