Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: is my api wrapper abstraction ok (is it perlish?)

by tobyink (Canon)
on Jan 19, 2013 at 07:28 UTC ( [id://1014177]=note: print w/replies, xml ) Need Help??


in reply to is my api wrapper abstraction ok (is it perlish?)

You are not calling your anonymous subs as methods, thus they don't get any invocant ($self). You could call them like this:

my $method = $a->answers->{answers_comments}; $a->answers->$method( 123, 134, 145, { order => "desc", sort => "votes", }, );

Then they'll have an invocant.

It would be much saner though to install your methods as genuine methods, not coderefs floating around attached to blessed objects.

# in Answers.pm use Sub::Name 'subname'; *answers_comments = subname( "Net::StackExchange::V2::Answer::answers_comments", one_param("answers","comments"), );

Now you can call it like a proper method:

$a->answers->answers_comments( 123, 134, 145, { order => "desc", sort => "votes", }, );
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Replies are listed 'Best First'.
Re^2: is my api wrapper abstraction ok (is it perlish?)
by gideondsouza (Pilgrim) on Jan 19, 2013 at 10:25 UTC

    Thanks a ton for your reply

    .Yep. This is the sorcery I was looking for.

    Is this from the Sub::Name module on cpan? It's not part of perls core modules right?

    May I ask, what language construct is this :  *answers_comments?? A pointer of some sort?

      *answer_comments is a glob - basically an entry in Perl's symbol table. It is kind of a bundle which contains sub answer_comments, our $answer_comments, our @answer_comments, our %answer_comments and the answer_comments bareword file handle.

      If you assign one glob to another, like *xxx = *yyy, then it makes sub xxx and sub yyy aliases for each other, and our $xxx and our $yyy aliases for each other, etc.

      use 5.010; use strict; use warnings; our ($xxx, $yyy, @xxx, @yyy); *xxx = *yyy; # alias $xxx = 42; say $yyy; # says "42" @xxx = (9,9,9); say "@yyy"; # says "9 9 9"

      Anyway, that's what happens when you assign one glob to another glob. But you can also assign references to a glob, in which is doesn't alias the whole bundle, but just the relevant slot within the glob. For example:

      use 5.010; use strict; use warnings; our ($xxx, $yyy, @xxx, @yyy); *xxx = \$yyy; # alias $yyy, but not @yyy $xxx = 42; say $yyy; # says "42" @xxx = (9,9,9); say "@yyy"; # says nothing

      And so one_param returns a coderef, and we can assign it to the glob:

      *answers_comments = one_param("answers","comments");

      This effectively installs the sub into the package with a given name. Almost as if you'd done:

      package ...; sub answers_comments { ...; }

      (This is what Exporter does internally - that module is not as magic as it seems.)

      I say "almost" though. There's one key difference, and that's what the CPAN module Sub::Name takes care of. When the answers_comments method is called, Perl still internally treats it as an anonymous coderef. Which means that stack traces (e.g. Carp) would show it as "__ANON__" rather than "answers_comments".

      Naming the sub is also important if you use something like namespace::autoclean which deletes subs it finds in your package that don't look like methods. Naming a sub makes it look like a method.

      So Sub::Name is well worth using when you muck around with globs; it's a shame it's not bundled with Perl.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        Thanks a lot for your explanation. I really appreciate it :)

        Sub::Name, on cpan has a 4 open bugs, I looked through them and I'm assuming that it should be ok to use it if I were distributing my wrapper as a module?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1014177]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-19 06:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found