Re: Notes about MooseX::Role::Parameterized

2010-04-26 Thread Kate Yoak

Karen,  thanks for the advice!

Let me see if I can get unconfused:

I don't want to pass a type parameter to the role - I want it to  
construct it!  This is why I have a builder.
I'd really like it to construct $type on its own, based on package  
name.  What's the best way to do that?  Or should I just quit being  
cute and do something like


with Role => {child => __PACKAGE__};

Come to think of it, it really isn't so bad.  :-)  Still, I am curious  
to understand if parameterized roles will support a real builder and  
how to achieve it.



On Apr 22, 2010, at 4:49 PM, Karen Etheridge wrote:



You are getting an error because the role is attempting to create an
attribute that doesn't exist, because you don't pass a type  
parameter to
the role.  You should mark that parameter as required, or check that  
it

exists first, e.g. one of:

parameter 'type' =>(
  isa => 'Str',
  required => 1,
  builder => '_type',
);

or:

if (my $type = $p->type)
{
   has $type =>(is => 'rw');
}

You could also use a default instead of a builder:

parameter 'type' =>(
  isa => 'Str',
  default => 'human',
);


The error message certainly isn't clear, and it suggests that the  
parameter
object does not exist at all in the parameterized role when you do  
not pass
a parameter (which does not parallel normal Moose behaviour -- an  
attribute
metaobject always exists on the object, even if one constructs an  
object

with no values).


On Thu, Apr 22, 2010 at 04:31:20PM -0700, Kate Yoak wrote:

Here is the most straightforward approach that fails with the error
above (the error occurs while trying to use Me):

package Role;
use MooseX::Role::Parameterized;

sub _type{  'human'; }

parameter 'type' =>(
  isa => 'Str',
  required => 0,
  builder => '_type',
);
role{
  my $p = shift;
  my $type = $p->type;
  has $type =>(is => 'rw');
};

1;

package Me;
use Moose;
with 'Role' => { };
1;



--
New and stirring things are belittled because if they
 are not belittled, the humiliating question arises,
   "Why then are you not taking part in them?" - H.G.Wells
   . ... .
Karen Etheridge, ka...@etheridge.ca   GCS C+++$ USL+++$ P+++$  
w--- M++
http://etheridge.ca/  PS++ PE-- b++ DI e++ h 
(-)




Re: Notes about MooseX::Role::Parameterized

2010-04-22 Thread Karen Etheridge

You are getting an error because the role is attempting to create an
attribute that doesn't exist, because you don't pass a type parameter to
the role.  You should mark that parameter as required, or check that it
exists first, e.g. one of:

parameter 'type' =>(
   isa => 'Str',
   required => 1,
   builder => '_type',
);

or:

if (my $type = $p->type)
{
has $type =>(is => 'rw');
}

You could also use a default instead of a builder:

parameter 'type' =>(
   isa => 'Str',
   default => 'human',
);


The error message certainly isn't clear, and it suggests that the parameter
object does not exist at all in the parameterized role when you do not pass
a parameter (which does not parallel normal Moose behaviour -- an attribute
metaobject always exists on the object, even if one constructs an object
with no values).


On Thu, Apr 22, 2010 at 04:31:20PM -0700, Kate Yoak wrote:
> Here is the most straightforward approach that fails with the error  
> above (the error occurs while trying to use Me):
> 
> package Role;
> use MooseX::Role::Parameterized;
> 
> sub _type{  'human'; }
> 
> parameter 'type' =>(
>isa => 'Str',
>required => 0,
>builder => '_type',
> );
> role{
>my $p = shift;
>my $type = $p->type;
>has $type =>(is => 'rw');
> };
> 
> 1;
> 
> package Me;
> use Moose;
> with 'Role' => { };
> 1;
> 

-- 
 New and stirring things are belittled because if they
  are not belittled, the humiliating question arises,
"Why then are you not taking part in them?" - H.G.Wells
. ... .
Karen Etheridge, ka...@etheridge.ca   GCS C+++$ USL+++$ P+++$ w--- M++
http://etheridge.ca/  PS++ PE-- b++ DI e++ h(-)


Re: Notes about MooseX::Role::Parameterized

2010-04-22 Thread Kate Yoak





parameter foo => (is => 'rw', builder => '_foo');

with _foo() defined above this statement, below it, inside the role
block (pretty sure it fails before getting inside the role).  No
good.  It says: Error:  Class::MOP::Class::__ANON__::SERIAL::1 does
not support builder method ...



You should have the builder method defined outside the role {}  
block, i.e.

at the same level as the parameter declaration itself.

Can you give an example where you would need to define the builder  
inside

the role block? This sounds rather strange to me.


HI Karen, thanks for the help.
No reason for the builder to be inside the role{} block.  I was just  
trying everything to make it work.


Here is the most straightforward approach that fails with the error  
above (the error occurs while trying to use Me):


package Role;
use MooseX::Role::Parameterized;

sub _type{  'human'; }

parameter 'type' =>(
   isa => 'Str',
   required => 0,
   builder => '_type',
);
role{
   my $p = shift;
   my $type = $p->type;
   has $type =>(is => 'rw');
};

1;

package Me;
use Moose;
with 'Role' => { };
1;



Re: Notes about MooseX::Role::Parameterized

2010-04-22 Thread Karen Etheridge
On Thu, Apr 22, 2010 at 03:25:41PM -0700, Kate Yoak wrote:
> Another issue:
> 
> Can parameter use builder and have it defined within the same module?
> 
> I've tried
> 
> parameter foo => (is => 'rw', builder => '_foo');
> 
> with _foo() defined above this statement, below it, inside the role  
> block (pretty sure it fails before getting inside the role).  No  
> good.  It says: Error:  Class::MOP::Class::__ANON__::SERIAL::1 does  
> not support builder method ...
> 
> What should I do?

You should have the builder method defined outside the role {} block, i.e.
at the same level as the parameter declaration itself.

Can you give an example where you would need to define the builder inside
the role block? This sounds rather strange to me.


-- 
  "I felt a kind of forlorn sense of being lost in a world of
  incredibly stupid and malicious dwarfs." - Aleister Crowley
. ... .
Karen Etheridge, ka...@etheridge.ca   GCS C+++$ USL+++$ P+++$ w--- M++
http://etheridge.ca/  PS++ PE-- b++ DI e++ h(-)


Re: Notes about MooseX::Role::Parameterized

2010-04-22 Thread Karen Etheridge
On Thu, Apr 22, 2010 at 02:54:07PM -0700, Kate Yoak wrote:
> Just a couple of notes that would be of use if they were in the  
> documentation:
> 
> 1. The bad news: Because of the weirdness of role{} block, the child,  
> nor the role cannot be declared within the same file with the script.   
> (Like you might do while trying to test sample functionality!)


Are you sure? e.g. have you tried including each namespace in its own
block?  Otherwise, each package is polluting each other's namespaces.
(Alternatively, you could use namespace::autoclean.)

{
package MyRole;
use MooseX::Role::Parameterized;
role {};
1;
}

{
package MyClass;
use Moose;
with MyRole => {};
1;
}

package main;

my $obj = MyClass->new();
print "obj is: " . $obj->dump(1);



-- 
   "Debugging is twice as hard as writing the code in the first place.
   Therefore, if you write the code as cleverly as possible, you are,
   by definition, not smart enough to debug it." - Brian W. Kernighan
. ... .
Karen Etheridge, ka...@etheridge.ca   GCS C+++$ USL+++$ P+++$ w--- M++
http://etheridge.ca/  PS++ PE-- b++ DI e++ h(-)


Re: Notes about MooseX::Role::Parameterized

2010-04-22 Thread Kate Yoak

Another issue:

Can parameter use builder and have it defined within the same module?

I've tried

parameter foo => (is => 'rw', builder => '_foo');

with _foo() defined above this statement, below it, inside the role  
block (pretty sure it fails before getting inside the role).  No  
good.  It says: Error:  Class::MOP::Class::__ANON__::SERIAL::1 does  
not support builder method ...


What should I do?

On Apr 22, 2010, at 2:54 PM, Kate Yoak wrote:

Just a couple of notes that would be of use if they were in the  
documentation:


1. The bad news: Because of the weirdness of role{} block, the  
child, nor the role cannot be declared within the same file with the  
script.  (Like you might do while trying to test sample  
functionality!)
2. The good news:  You can declare regular attr and methods outside  
of the role block (only parameterized declarations need to be there)


 e.g. the following orphaned role is legal:

package Role;
use MooseX::Role::Parameterized;

has name => (is => 'rw');

role{};

1;

  The usefulness is in the realization that not the entirety of the  
role must belong in the role {} block - but just the parameterized  
part.


That said, I am very excited about the functionality! Thanks!