<?xml version="1.0" encoding="windows-1252"?>
<node id="1014174" title="is my api wrapper abstraction ok (is it perlish?)" created="2013-01-19 01:36:42" updated="2013-01-19 01:36:42">
<type id="115">
perlquestion</type>
<author id="1005218">
gideondsouza</author>
<data>
<field name="doctext">
&lt;p&gt;I beseech you dear monks to read my question. I know its a bit of code and text but I made good efforts to keep it tight&lt;/p&gt;

&lt;p&gt;I'm on the learning road and I'm building an API wrapper as practise. Note, I'm not using Moose/Moo and building this to learn perl and perl OOP&lt;/p&gt;

&lt;p&gt;I'm writing a wrapper over &lt;a href='http://api.stackexchange.com/docs'&gt; stack exchange api.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usage would look like this (currently &lt;b&gt;prints urls&lt;/b&gt; for testing) :&lt;/p&gt;
&lt;code&gt;
# for the following API urls:
##http://api.stackexchange.com/answers/{ids}/comments/?query_str
##http://api.stackexchange.com/answers/?query_str
use Net::StackExchange;
my $a = Net::StackExchange-&gt;new();				
print $a-&gt;answers-&gt;{answers_comments}-&gt;(123,134,145,{ 
				   						order=&gt; "desc",
				   						sort=&gt;"votes"
										});

######## THE ABOVE PRINTS:
#http://api.stackexchange.com/answers/123;134;145/comments?sort=votes&amp;order=desc
print $a-&gt;answers-&gt;{answers}-&gt;({ 
		   				order=&gt; "desc",
		   				sort=&gt;"votes"
						});

######## THE ABOVE PRINTS:
#http://api.stackexchange.com/answers/?sort=votes&amp;order=desc
&lt;/code&gt;
&lt;p&gt;Mostly urls are of the form &lt;i&gt;api/{name}/{ids_list}/{anothename}&lt;/i&gt; &lt;b&gt;or&lt;/b&gt; &lt;i&gt;api/{name}/&lt;/i&gt;. After that there are query params which are represented by a hash in my code.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;My questions&lt;/b&gt; begin:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; Does the consumer code look ok? Is it neat enough abstraction to  have anonymous functions like this: &lt;i&gt;$object-&gt;answers-&gt;{answers_comments}-&gt;(..)&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Is there I way I can build methods so my &lt;b&gt;consumer code&lt;/b&gt; looks like  &lt;i&gt;$object-&gt;answers-&gt;answers_comments()&lt;/i&gt; would that be correct/better/perl-ish?&lt;/li&gt;
&lt;li&gt; Inside my anonymous why don't I have a reference to $self?&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;b&gt;My Code&lt;/b&gt;

&lt;p&gt;On my disk it looks like this:&lt;/p&gt;

&lt;pre&gt;
Net-StackExchange/
&amp;#9500;&amp;#9472;&amp;#9472; Changes
&amp;#9500;&amp;#9472;&amp;#9472; MANIFEST
&amp;#9500;&amp;#9472;&amp;#9472; Makefile.PL
&amp;#9500;&amp;#9472;&amp;#9472; README
&amp;#9500;&amp;#9472;&amp;#9472; ignore.txt
&amp;#9500;&amp;#9472;&amp;#9472; lib
&amp;#9474;   &amp;#9492;&amp;#9472;&amp;#9472; Net
&amp;#9474;       &amp;#9500;&amp;#9472;&amp;#9472; StackExchange
&amp;#9474;       &amp;#9474;   &amp;#9500;&amp;#9472;&amp;#9472; V2
&amp;#9474;       &amp;#9474;   &amp;#9474;   &amp;#9500;&amp;#9472;&amp;#9472; Answers.pm
&amp;#9474;       &amp;#9474;   &amp;#9474;   &amp;#9492;&amp;#9472;&amp;#9472; Common.pm
&amp;#9474;       &amp;#9474;   &amp;#9492;&amp;#9472;&amp;#9472; V2.pm
&amp;#9474;       &amp;#9492;&amp;#9472;&amp;#9472; StackExchange.pm
&amp;#9492;&amp;#9472;&amp;#9472; t
    &amp;#9500;&amp;#9472;&amp;#9472; 00-load.t
    &amp;#9500;&amp;#9472;&amp;#9472; boilerplate.t
    &amp;#9500;&amp;#9472;&amp;#9472; manifest.t
    &amp;#9500;&amp;#9472;&amp;#9472; pod-coverage.t
    &amp;#9492;&amp;#9472;&amp;#9472; pod.t
&lt;/pre&gt;

&lt;p&gt;The code in each of the FOUR pm files&lt;/p&gt;

&lt;code&gt;
###################
#   Inside StackExchange.pm
###################
sub new {
    return Net::StackExchange::V2-&gt;new();
}
###################
#   Inside V2.pm
###################
sub new {
    my ($class) = @_;
    my $self = {};
    bless $self, $class;
    return $self;
}
sub answers {
    return Net::StackExchange::V2::Answers-&gt;new();
}
###################
#   Inside Answers.pm
###################
use Net::StackExchange::V2::Common qw(query no_params one_param);

sub new {
	my ($class) = @_;
    my $self = {
                site =&gt; "stackoverflow",
		answers =&gt; no_params("answers"),
		answers_comments =&gt; one_param("answers","comments"),
    };
    bless $self, $class;
    return $self;
}
#################################################
#################################################
# THIS IS WHAT NEEDS ATTENTION
#   Inside Common.pm
#################################################
use constant BASE_URL =&gt; "http://api.stackexchange.com/";
our @ISA = qw(Exporter);
our @EXPORT = qw(query no_params one_param);
sub query {
        #get the hash from the last param and use it for the query str
	my $queryStrHash = pop @_; 
        #add rest of the params into the url.
	my $url = join("/",@_);
	my @params = ();
	while ( my ($key, $value) = each(%$queryStrHash) ) {
		push @params, $key."=".$value;
    }
	my $query = '?'.join '&amp;',@params;
	return BASE_URL.$url.$query;
}
##function to generate a function that generates url with 
#a name and no parameters..
sub no_params {
#WHY don't I get $self  = shift here?
	my $name = shift;
	return sub {
#WHY don't I get $self  = shift here?
		my $queryStr = pop @_;
		return query($name, $queryStr);
	}
}
##function to generate a function that generates url 
#with a name and one parameter..
sub one_param {
	my $param1 = shift;
	my $param2 = shift;
	return sub {
		my $q = pop @_;
		my @ids = @_;
		return query($param1, join(";",@ids), $param2, $q);
	}
}
&lt;/code&gt;</field>
</data>
</node>
