Re: Trying to create an attribute trait that prompts for a value if none specified

[email protected] ("Todd Lorenz")
Newsgroups perl.moose
Message-ID <[email protected]>
Not quite... We're not changing the default metaclass for everything, but 
rather applying a metarole to the metaclass of the consuming class. (I think 
that's how it goes -- I'm still not sure of the correct terminology.) And 
there's still an attribute "trait" involved there, albeit a minimal one that 
adds a "prompt" option to affected attributes. The 
new_object/_inline_new_object wrappers simply look for those attributes at 
the end of construction and ask the user to fill in the blanks. (If you're 
concerned about prompting during cloning and/or reblessing, there'll be a 
little more work to do.) Don't know if it's a good approach by Moose Cabal 
standards, but it's direct. You'd want to add in other stuff probably, like 
mutual exclusion with defaults, etc.

-----Original Message----- 
From: Buddy Burden
Sent: Thursday, December 22, 2011 2:40 PM
To: Edward Allen
Cc: [email protected]
Subject: Re: Trying to create an attribute trait that prompts for a value if 
none specified

Guys,

I'm still experimenting here, but I had a couple of questions.


ealleniii,

I like your solution; very clever, particularly where you install the
bulder sub as a default instead of a builder, which neatly gets around
the problem that a builder has to be the name of a method of the
class.  But the crux of it is here:

>            # The real magic:
>            $attr = $attr->clone_and_inherit_options(
>                default => $builder,
>                lazy => 1
>            );
>            $class->add_attribute($attr);

and my gut instinct is to wonder: doesn't that mean the attribute gets
added to the class twice?  Now, admittedly I haven't actually tried it
yet, but it also occurred to me to wonder how you could even _tell_ if
the attribute was installed twice ... could it conceivably generate a
silent failure that just resulted in weirdness down the road? or
something that works today but not tomorrow when Moose guts are
changed?

If the author--or anyone else--has some insight on that issue, I'd
really love to hear it.


Todd,

I'm assuming you replied off-list just because you didn't want the zip
file to land in everyone's inbox, for which I'm sure they're
appreciative. :-)  So, after staring at your approach for quite a
while, I finally figured out what's going on: you're actually
_changing_ the default metaclass for everything by applying a new role
to it.  Said new role contains this:

>     around new_object => sub {
>
>         my ($orig_method, $self_aka_class) = (shift, shift);
>
>         my $instance = $self_aka_class->$orig_method(@_);
>
>         for my $attr ($self_aka_class->get_all_attributes) {
>
>             next unless $attr->has_prompt;
>
>             unless ($attr->has_value($instance)) {
>
>                 my $prompted_val = Term::Prompt::prompt('x', 
> $attr->prompt, 'help prompt', 'foo');
>
>                 $attr->set_value($instance, $prompted_val);
>             }
>         }
>
>         return $instance;
>     };

Again, very clever.  But definitely very different from the approach I
was going for, which was an attribute trait.  (Although the provided
test file proves handily that it really works.)  Can you--or
anyone--tell me what the practical differences would be between the
two approaches, and why I might prefer one over the other?


Thanx again for the help guys.


            -- Buddy
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.