I had a similar problem.  Try this:

============== start

#!/usr/bin/perl -w


{
    package MooseX::Trait::PromptBuilder;
    use Moose::Role;

    after 'install_accessors' => sub {
        my ($attr, $inline, $class) = @_;
        $attr->create_builder($class);
    };

    # Replace this!  Add type checking, color, dancing bears, etc.
    sub ask_away {
        my ($attr) = @_;
        return sub {
            print "Value for " . $attr->name . ": ";
            my $resp = <STDIN>;
            chomp $resp;
            return ($resp eq "") ? undef : $resp;
        }
    }

    has __ask_builder_built => (
        isa => 'Bool',
        reader => '_has_ask_builder',
        writer => '_set_has_ask_builder'
    );


    sub create_builder {
        my $attr = shift;
        my $class = shift || $attr->associated_class;

        # To prevent recurssion
        return if  $attr->_has_ask_builder;
        $attr->_set_has_ask_builder(1);

        # You do not need this, but someday you may:
        if ($attr->associated_class->is_immutable) {
            Moose->throw_error(
            q{Class }, $attr->associated_class,
            q{is immutable. Run create_builder before make_immutable});
        }

        my $builder = $attr->ask_away();

        if ($attr->has_builder) {
            $attr->associated_class->add_around_method_modifier($attr->builder,
                sub {
                    my ($orig,$instance,@params) = @_;
                    for my $code ($builder,$orig) {
                        my $return = $instance->$code(@params);
                        if (defined $return) { return $return }
                    }
                    return;
                }
            );
        }
        else {
            # The real magic:
            $attr = $attr->clone_and_inherit_options(
                default => $builder,
                lazy => 1
            );
            $class->add_attribute($attr);
        }
    }

    1;
}

{
    package MyApp;
    use Moose;

    has toes => (
        is => "Int",
        is => "ro",
        traits => [ 'MooseX::Trait::PromptBuilder' ],
        # DO NOT USE default ATTRIBUTE
        builder => '_build_toes',
    );

    sub _build_toes { 12 }
}


my $app1 = MyApp->new();

print "I have: ", $app1->toes , "\n";



==========end
I reserve no rights to the above, if you have to ask.

---ealleniii

On Wed, Dec 21, 2011 at 8:45 PM, Buddy Burden <barefootco...@gmail.com> wrote:
>
> Guys,
>
> Okay, basically what I want is just what the subject says: you might
> declare your attribute something like so:
>
>    has value => ( traits => [qw< Promptable >], is => 'rw', isa =>
> 'Int', prompt => 'Please enter a value:' );
>
> then, for each instance, if you provide a value in new(), that's the
> value; if you don't, it prompts the user for it.  The basic idea is I
> can use this with MooseX::App::Cmd for switches that are not provided
> on the command-line.
>
> So, my first approach was to around attach_to_class and just stick a
> builder method in.  But you can't actually _set_ a builder, because
> builder is essentially a read-only attribute of the attribute
> metaclass.
>
> Okay, no problem: I'll just intercept BUILDARGS for the attribute
> metaclass and slip a builder in there as if the client had specified
> it.  No go:
>
> > The method 'BUILDARGS' was not found in the inheritance hierarchy for 
> > Moose::Meta::Class::__ANON__::SERIAL::15 at 
> > /usr/local/lib64/perl5/Class/MOP/Class.pm line 1048
>
> I guess roles can't mess with the BUILDARGS for the classes they're
> composed into ... ?  I could imagine that being a reasonable
> restriction.
>
> Okay, next try:  I'll around initialize_slot_instance for the
> attribute metaclass and prompt right there, and slip the user-supplied
> value into $params before passing it onto $orig (only if not already
> there and after validation, natch).  But my around method for
> initialize_slot_instance is never called, it seems ... not sure why
> ... because it's being supplied by a role? because the new() is being
> inlined? other?
>
> So now I'm out of ideas.  Can anyone tell me what's wrong with any of
> the approaches, or if there's a whole 'nother approach that I should
> be using? or maybe there's some helpful module I've missed in my CPAN
> searches?  Anything?  I'd really appreciate it.
>
> Thanx for all you do, Moosites.  Moose makes my job easier every day.
> Keep up the good work.
>
>
>             -- Buddy

Reply via email to