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
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
I'm writing a wrapper over stack exchange api.
Usage would look like this (currently prints urls for testing) :
# 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->new();
print $a->answers->{answers_comments}->(123,134,145,{
order=> "desc",
sort=>"votes"
});
######## THE ABOVE PRINTS:
#http://api.stackexchange.com/answers/123;134;145/comments?sort=votes&
+order=desc
print $a->answers->{answers}->({
order=> "desc",
sort=>"votes"
});
######## THE ABOVE PRINTS:
#http://api.stackexchange.com/answers/?sort=votes&order=desc
Mostly urls are of the form api/{name}/{ids_list}/{anothename} or api/{name}/. After that there are query params which are represented by a hash in my code.
My questions begin:
- Does the consumer code look ok? Is it neat enough abstraction to have anonymous functions like this: $object->answers->{answers_comments}->(..)
- Is there I way I can build methods so my consumer code looks like $object->answers->answers_comments() would that be correct/better/perl-ish?
- Inside my anonymous why don't I have a reference to $self?
My Code
On my disk it looks like this:
Net-StackExchange/
├── Changes
├── MANIFEST
├── Makefile.PL
├── README
├── ignore.txt
├── lib
│ └── Net
│ ├── StackExchange
│ │ ├── V2
│ │ │ ├── Answers.pm
│ │ │ └── Common.pm
│ │ └── V2.pm
│ └── StackExchange.pm
└── t
├── 00-load.t
├── boilerplate.t
├── manifest.t
├── pod-coverage.t
└── pod.t
The code in each of the FOUR pm files
###################
# Inside StackExchange.pm
###################
sub new {
return Net::StackExchange::V2->new();
}
###################
# Inside V2.pm
###################
sub new {
my ($class) = @_;
my $self = {};
bless $self, $class;
return $self;
}
sub answers {
return Net::StackExchange::V2::Answers->new();
}
###################
# Inside Answers.pm
###################
use Net::StackExchange::V2::Common qw(query no_params one_param);
sub new {
my ($class) = @_;
my $self = {
site => "stackoverflow",
answers => no_params("answers"),
answers_comments => one_param("answers","comments"),
};
bless $self, $class;
return $self;
}
#################################################
#################################################
# THIS IS WHAT NEEDS ATTENTION
# Inside Common.pm
#################################################
use constant BASE_URL => "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 '&',@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);
}
}
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.