in reply to Moo error message not understood

Its your basic order of compilation deal ...

Lib::Book->new happens before  has isbn happens ...

basically because that is what you typed, at the time new is called the class doesn't have isbn yet

If you add  BEGIN { ... } around package Lib::Book, all that should happen before Lib::Book->new as you expect

Don't know where all this is documented, maybe Simple Module Tutorial ... maybe its also discussed in tyes template at (tye)Re: Stupid question (and see one discussion of that template at Re^2: RFC: Creating unicursal stars

Replies are listed 'Best First'.
Re^2: Moo error message not understood (BEGIN block missing)
by davies (Monsignor) on Jan 17, 2014 at 19:35 UTC

    Thanks. Your advice works perfectly, but I'm still confused. I don't see how, if the "new" happens before "has", the text gets into the object as shown by Data::Dumper. Maybe I shouldn't be worrying, but I'm scared there's a trap lying in wait for me.

    Regards,

    John Davies

    Update: Thanks again. I won't pretend to understand everything at first glance late on a Friday evening, but it's a relief to know that there is a sound explanation. I will work through it, but I won't guarantee how many attempts it will take to get it into my skull. I knew there were aspects of Perl I didn't have a clue about, and this is clearly one that I need to understand better.

      the text gets into the object as shown by Data::Dumper.

      Yes it does ... doesn't mean there is an accessor created (accessors are just "methods" aka "subroutines")

      without has bar

      use Data::Dump qw/ dd /; dd( my $f = Foo->new(qw/ bar 1 /) ); $f->bar; {package Foo; use Moo; } __END__ bless({ bar => 1 }, "Foo") Can't locate object method "bar" via package "Foo" at - line 3.

      you can cheat and use $f->{bar} ... this is cheating / breaking encapsulation / peeking inside object / not using official api / so if sometime in the future you internally rename bar attribute to barps, anyone using ->{bar} would have to update program, anyone using the documented api ->bar wouldn't (because you'd update that too) ... yeah seems convoluted example but thats how they work :)

      with has bar Without BEGIN block there is no bar accessor (accessor is subroutine ... all $obj->whatever is subroutines)

      use Data::Dump qw/ dd /; dd( my $f = Foo->new(qw/ bar 1 /) ); $f->bar; {package Foo; use Moo; has( qw/ bar is rw / ); } __END__ bless({ bar => 1 }, "Foo") Can't locate object method "bar" via package "Foo" at - line 3.

      with has bar and With BEGIN block no death :)

      use Data::Dump qw/ dd /; dd( my $f = Foo->new(qw/ bar 1 /) ); $f->bar; BEGIN{package Foo; use Moo; has( qw/ bar is rw / ); } __END__ bless({ bar => 1 }, "Foo")

      with has bar and Without begin block no death (moved to line 1)

      {package Foo; use Moo; has( qw/ bar is rw / ); } use Data::Dump qw/ dd /; dd( my $f = Foo->new(qw/ bar 1 /) ); $f->bar; __END__ bless({ bar => 1 }, "Foo")

      got that? See also perlobj, A Method is Simply a Subroutine, Attributes