gideondsouza has asked for the wisdom of the Perl Monks concerning the following question:
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); } }
|
---|
Back to
Seekers of Perl Wisdom