Perl and Mac OS X versions

2010 February 3
tags: ,
by draegtun

Apple website has an opensource page: http://www.opensource.apple.com/, which lists all its products and components which have and use opensource technology.

If you go here: http://www.apple.com/opensource/, it provides a complete list of opensource projects that Apple uses.

In this list is of course Perl. From this we can see which version of Perl was compiled on Mac OS X. We can also see what options, patches, fixes & extra modules were included.

So I’ve been able to glean these Perl versions that Apple have used with Mac OS X:

  • 5.10.0 & 5.8.9 (perl-63)
  • 5.8.8 (perl-51 patches: perl-51.1.1, perl-51.1.4)
  • 5.8.6 (perl-38 patch: perl-38.1)
  • 5.8.6 (perl-35 patch: perl-35.1.1)
  • 5.8.4 (perl-28.2)
  • 5.8.1-RC3 (perl-25.2)
  • 5.8.1 (perl-24.1) “Maintenance release working toward v5.8.1″
  • 5.6.0 (perl-21)
  • 5.6.0 (perl-17)

Now which one(s) are tied to which Mac OS X is still in the air a bit! This is my best stab at it:

  10.6    5.10.0 & 5.8.9      perl-63
  10.5    5.8.8               perl-51
  10.4    5.8.6               perl-38 or perl-35
  10.3    5.8.4 or 5.8.1 ?
  10.2    5.8.1 ?
  10.1    5.6.0               ? perl-21 and/or perl-17
  10.0    5.6.0 ?

Hopefully this information is useful to someone

/I3az/

refs:

Mac OS X “Snow Leopard” (10.6) and Perl

2010 January 24
by draegtun

Snow Leopard ships with multiple versions of Perl:

  • 5.10.0 (64 bit)
  • 5.10.0 (32 bit)
  • 5.8.9 (32 bit)

The default Perl is 5.10.0 (64 bit). However you can change this to 32-bit Perl by setting the following ENV shell variable:

export VERSIONER_PERL_PREFER_32_BIT=yes

And to switch to 5.8.9 all you need is this ENV variable set:

export VERSIONER_PERL_VERSION=5.8.9

Instead of setting these ENV variables in your Terminal sessions you can also make the change to the systems defaults:

  • defaults write com.apple.versioner.perl Prefer-32-Bit -bool yes
  • defaults write com.apple.versioner.perl Version 5.8.9

This is a interesting move by Apple and something which may come in very handy in the future.

As it stands at this moment though you probably want 5.10.1 (and beyond) because of issues with 5.10.0. So you will probably be looking down the compiling route anyway. Still it does give the future option of a local::lib possibility with the pre-installed Perl provided by Apple.

NB. I always recommend that you avoid installing modules with CPAN (shell) on OS provided Perl. Always stick to the OS provided package installer to update Perl & modules (which unfortunately for Mac’s means “zilch” :( Apple “Software Updater” may update Perl itself but no extra modules are provided above what Apple provides on top of core Perl)

/I3az/

References:

Anyone for Perl 6 metaprogramming?

2010 January 14
by draegtun

My last post about the Metaprogramming: Ruby vs. Javascript blog post stirred a little thought in my head:

How would it look in Perl 6?

Well here goes, the complete example written in Perl 6 which runs on Rakudo, an implementation of the Perl 6 spec on the Parrot VM:

use v6;

class Ninja {
    has Str $.name is rw;
}

my Ninja $drew .= new( name => 'Drew' );
my Ninja $adam .= new( name => 'Adam' );

###########################################################
# Reopen Ninja class ("is also" does the biz)
# and add 'battle_cry' method

class Ninja is also {
    method battle_cry {
        say $.name ~ ' says zing!!!';
    }
}

$drew.battle_cry;   # => Drew says zing!!!
$adam.battle_cry;   # => Adam says zing!!!

###########################################################
# add 'throw_star' method to $drew object by creating
# and applying ("does") role to it (Singleton method)

role ThrowStar {
    method throw_star { say "throwing star" }
}

$drew does ThrowStar;
$drew.throw_star;     # => throwing a star

###########################################################
# call method dynamically: $obj.'method_name' or $obj.$method

$drew.'battle_cry';     # => Drew says zing!!!

###########################################################
# add "colour" method closing over $colour_name (ie. closure):

my $colour_name = 'black';

class Ninja is also {
    method colour { say "{$.name}'s colour is {$colour_name} " }
}

$drew.colour;    # => Drew's colour is black
$adam.colour;    # => Adam's colour is black

###########################################################

# "defining a method dynamically on an instance that closes
# over local scope and accesses the instance’s state"

my $sword_symbol = '********';

$drew.^add_method( 'swing', method ( Str $sound_effect ) {
    say "{$.name}: {$sword_symbol} {$sound_effect}";
});

$drew.swing( 'slash!!' );    # => Drew: ********* slash!!

Of all the examples (in Perl 5 / Moose, Ruby, Javascript & Python) I think this one is the most clean and intuitive. Perl 6 has a good future if it keeps this up!

And it all went surprising smoothly. There were a couple of bumps in my Perl 6 road but these are all connected to the flux between the Perl 6 spec, Rakudo and knowing what info you find on the web is still accurate (or not).

First bump was how to re-open a class. Most Perl 6 documentation implied that classes were always open (unless is final was used). This no longer seemed to be the case and it gave examples of class A is augmented { ... }. However this didn’t work in Rakudo but eventually I came across is also which did.

I like the look of class A is also { ... }. However Moritz on IRC #perl6 mentioned that the Perl 6 spec had changed so my example would need to be:

augment class Ninja {
    method battle_cry {
        say $.name ~ ' says zing!!!';
    }
}

Rakudo is currently a bit behind Perl 6 spec here but above will replace is also shortly. The change to augment makes sense because it avoids any confusion with roles in the class declaration.

The second bump was how to create a method dynamically. Now being familiar with Moose I had expected the following to work:

Ninja.meta.add_method( 'swing', method ( Str $sound_effect ) {
    say "{$.name}: {$sword_symbol} {$sound_effect}";
});

And according to most Perl 6 docs .meta was the method to access the metaclass (MOP). However meta produced a method not defined error :(

Trawling the web further I did find that you could do:

Ninja.swing = method { say "Changed to zing" };

But this only allowed you to redefine a method, not create a new one.

Luckily IRC #perl6 came to the rescue again! jnthn & Moritz pointed me to $object.^add_method( ... ) and the docs on the ng branch of Rakudo on Github.

Perl6 does have some beautiful syntax. I love the $drew does Throwstar line. Soon Rakudo will be able to do:

$drew does role {
    method throw_star { say "throwing star" }
};

So this, augment and probably lots more will be part of the ng branch which will be merged with the Rakudo master in the not too distant future.

/I3az/

Anyone for metaprogramming?

2010 January 13

What is metaprogramming? Well this question caused a heated discussion on Hacker News yesterday.

I personally would describe that metaprogramming provides the ability to:

transform programs with programs

and leave it at that!

The article that stirred the metaprogramming pot was Metaprogramming: Ruby vs. Javascript. This actually is a good post and it helped fill in a few holes in my “fragile” Javascript knowledge.

Luckily I believe my Perl is a bit less fragile!, so I thought I would convert the metaprogramming examples into Perl & Moose.

So following the blogs examples, below defines the Ninja class in Moose. MooseX::SingletonMethod loads Moose with a bit of singleton method sugar.

use Modern::Perl;

{
    package Ninja;
    use MooseX::SingletonMethod;
    use namespace::clean -except => 'meta';

    has name => ( is => 'rw', isa => 'Str' );
}

my $drew = Ninja->new( name => 'Drew' );
my $adam = Ninja->new( name => 'Adam' );

NB. namespace::clean stops the Moose sugar percolating into Ninja class (except meta… which is the Meta Object Protocol method… which handy for metaprogramming!).

Now we re-open the Ninja class and add battle_cry method like so:

{
    package Ninja;

    sub battle_cry {
        my $self = shift;
        say $self->name . ' says zing!!!';
    }
}

$drew->battle_cry;   # => Drew says zing!!!
$adam->battle_cry;   # => Adam says zing!!!

Now using MooseX::SingletonMethod we add throw_star singleton method into $drew object:

$drew->add_singleton_method( throw_star => sub {
    say "throwing star";
});

$drew->throw_star;   # => throwing a star

To call method dynamically we do this:

$drew->${ \'battle_cry' };   # => Drew says zing!!!

Create colour method closing over $colour_name (ie. closure):

my $colour_name = 'black';

Ninja->meta->add_method( colour => sub {
    my $self = shift;
    say "${ \$self->name }'s colour is $colour_name";
});

$drew->colour;    # => Drew's colour is black
$adam->colour;    # => Adam's colour is black

Finally… “defining a method dynamically on an instance that closes over local scope and accesses the instance’s state”

my $sword_symbol = '********';

$drew->add_singleton_method( swing => sub {
    my ($self, $sound_effect) = @_;
    say "${ \$self->name }: $sword_symbol $sound_effect";
});

$drew->swing( 'slash!!' );   # => Drew: ********* slash!!

Everything nicely works the same as the Ruby & Javascript blog examples.

To round things off, below is the complete example but with MooseX::Declare sugar stirred into the pot.

use Modern::Perl;
use MooseX::Declare;

class Ninja with MooseX::SingletonMethod::Role is mutable {
    has name => ( is => 'rw', isa => 'Str' );
}

my $drew = Ninja->new( name => 'Drew' );
my $adam = Ninja->new( name => 'Adam' );

###########################################################

class Ninja is mutable {
    method battle_cry {
        say $self->name . ' says zing!!!';
    }
}

$drew->battle_cry;   # => Drew says zing!!!
$adam->battle_cry;   # => Adam says zing!!!

###########################################################

$drew->add_singleton_method( throw_star => sub {
    say "throwing star";
});

$drew->throw_star;   # => throwing a star

###########################################################

$drew->${ \'battle_cry' };   # => Drew says zing!!!

###########################################################

my $colour_name = 'black';

Ninja->meta->add_method( colour => sub {
    my $self = shift;
    say "${ \$self->name }'s colour is $colour_name";
});

$drew->colour;    # => Drew's colour is black
$adam->colour;    # => Adam's colour is black

###########################################################

my $sword_symbol = '********';

$drew->add_singleton_method( swing => sub {
    my ($self, $sound_effect) = @_;
    say "${ \$self->name }: $sword_symbol $sound_effect";
});

$drew->swing( 'slash!!' );   # => Drew: ********* slash!!

/I3az/

PS. If you want Moose in Javascript then have a look at Joose

Receiving contributions to your Github project

2010 January 4
tags: , ,
by draegtun

Received my first ever contribution to one of my Github projects today. A pull request from a cpanservice? And I wasn’t the only one or was wondering who this cpanservice is or was?

I suspect that this as something to do with the recent gitPAN upload to Github and therefore is probably some automated service that is going through related projects making sure that Github CPAN projects do have the meta repository tag populated in the build process.

NB. I blogged about this repository link back in May but forgot to put my changes live. *blush*

This contribution was the necessary nudge I needed to find out how to use git to merge in external changes. Github itself did seem to provide a web option to apply this change directly under “Fork Queue”. However I wanted to do it all via git so first place I looked is the Github documention on pull requests.

My local directory was up-to-date so I just needed to do the following to pull & merge into my code:

  • git pull git://github.com/cpanservice/builder.git master

All merged and committed (see PS). Quick check of diffs & logs and then just needed to populate it back to Github:

  • git push origin master

You will see cpanservice changes immediately in the commits. However the Github graphs and fork queue take a little while to be updated to show the merge.

/I3az/

 

PS. The merged cpanservice changes showed up under me in the network graph (see red line below) despite showing up correctly under commits.

github-builder-graph

I think this is because I merge changes locally and then pushed back to Github? Its not an issue for these cpanservice changes but I would like to get it right for “proper” contributors.

So I think the alternate merge example documented by Github might be the better approach?

git remote add defunkt git://github.com/defunkt/grit.git
git fetch defunkt
git merge defunkt/master

Couple of CPAN pressies

2009 December 26
by draegtun

Just uploaded a couple of new modules to CPAN:

The first one you is just a small xmas cracker that you will already know about from my “bare URL” post from last week. Just pull, enjoy for a little while and then chuck away like most xmas cracker toys :)

The second one is a tad similar (ie. Devel::Declare) but with a much more sympathetic syntax by allowing you to create new Quote-Like Operators in Perl with Perl.

For a good end product exemplar have a look at PerlX::QuoteOperator::URL included with the distribution:

use PerlX::QuoteOperator::URL 'qh';

my $content = qh{ http://transfixedbutnotdead.com/ };

There is no scary parsing going on with this example. PerlX::QuoteOperator / Devel::Declare simply hits the ‘qh’ keyword and converts it to:

qh qq{ http://transfixedbutnotdead.com/ }

And ‘qh’ is a subroutine with a ($) prototype. So nothing too sinister (unless you really do abhor subroutine prototypes!), just a simple macro which gives the appearance that we have new quote-like operators.

Certainly an interesting concept to be able to produce new quote-like operators in Perl. So hopefully PerlX::QuoteOperator might find its way under a few xmas trees :)

Merry Xmas & happy St. Stephen’s day to everyone.

/I3az/

PS. I chose the PerlX::* because gugod as already provided some wonderful Devel::Declare Perl extending modules under this namespace. I feel its in the same vein so hopefully a good place for it to live.

Contributing to a project on Github

2009 December 24
by draegtun

After getting my head into Devel::Declare::Context::Simple to create the bare URL for my last blog post
I realised that I’ve percolated enough knowledge about the module that it would be a good idea to redirect it back to the project by at least doing the POD.

This will be the first time I’ve “properly” contributed in some form to an opensource project (“properly” being via source control management & a patch).

Devel::Declare is hosted on Github here. And the process to contribute back changes to a Github project is “forking” simple!

With Git & Github its all about forking. Here is a concise Github howto (which I’ll regurgitate below with my own slant & spiel!).

I only use Git for my Github projects, so forking etc is all new to me. To break it down into a few simple steps the process to contribute would be:

  • Fork project
  • Clone your fork
  • Make your changes
  • Push changes back to you fork
  • Send pull request back to original project

 

Here are the minutiae steps I went through for Devel::Declare:

  • Went to Devel::Declare project on Github and forked it.
  • Forked project now appears in my project list.
  • Cloned my forked Devel::Declare (use “Your Clone URL” copy/paste)
    git clone git@github.com:draegtun/devel-declare.git
    cd devel-declare/

  • Linked my forked project to original
    git remote add upstream git://github.com/rafl/devel-declare.git
    git fetch upstream

  • Make my changes to project
  • Run tests (in case I did something stupid!)
    perl Makefile.PL
    make
    make test

  • Clear down build once happy
    make realclean

  • Push my changes back to my fork
    git commit -a -m "Documentation added to D::D::Context::Simple + examples directory"
    git push origin master

Now on Github the changes can be seen in my fork

All I do now is click the “pull request” button and off went a request of my changes to rafl. Fingers cross my documentation changes were good enough to be accepted.

So I’m no longer a virgin to contributing to this opensource malarky :)

/I3az/

URL, Devel::Declare and no strings attached

2009 December 16
by draegtun

This Hacker News article caught my eye yesterday which pointed to a blog post about having a raw URL within a Ruby program using some clever shenanigans. (They you go, I saved you having to click through to find all the links yourself!)

Some examples from blog post:

# display this JSON request
puts http://github.com/defunkt.json

# => "He nose the truth."
require 'json'
url = http://twitter.com/statuses/show/6592721580.json
JSON.parse(url.to_s)['text']

Very clever indeed. Of course there will be some edge cases but it does show you how far you can stretch Ruby. NB. Didn’t work in 1.9 for me but worked with minor warning in 1.8.2 (yes I know it old but thats what shipped with Mac OSX Tiger).

So how far can we stretch Perl? Well with Devel::Declare it can be stretched all the way:

use Modern::Perl;
use JSON qw(decode_json);
use URLDSL;

# print the json
say http://twitter.com/statuses/show/6592721580.json;

# => "He nose the truth."
say decode_json( http://twitter.com/statuses/show/6592721580.json )->{text};

So Perl also has no strings attached ;-)

Devel::Declare allow us to extend the Perl syntax in a robust and easy fashion:

package URLDSL;
use Modern::Perl;
use Devel::Declare ();
use LWP::Simple ();
use base 'Devel::Declare::Context::Simple';

sub import {
    my $class  = shift;
    my $caller = caller;
    my $ctx    = __PACKAGE__->new;

    Devel::Declare->setup_for(
        $caller,
        {
            http => {
                const => sub { $ctx->parser(@_) },
            },
        },
    );

    no strict 'refs';
    *{$caller.'::http'} = sub ($) { LWP::Simple::get( $_[0] ) };
}

sub parser {
    my $self = shift;
    $self->init(@_);
    $self->skip_declarator;          # skip past "http"

    my $line = $self->get_linestr;   # get me current line of code
    my $pos  = $self->offset;        # position just after "http"
    my $url  = substr $line, $pos;   # url & everything after "http"

    for my $c (split //, $url) {
        # if blank, semicolon or closing parenthesis then no longer a URL
        last if $c eq q{ };
        last if $c eq q{;};
        last if $c eq q{)};
        $pos++;
    }    

    # wrap the url with http() sub and quotes
    substr( $line, $pos,          0 ) = q{")};
    substr( $line, $self->offset, 0 ) = q{("http};

    # pass back changes to parser
    $self->set_linestr( $line );

    return;
}

1;

 

Here is a low level synopsis of how it worked:

  • Devel::Declare tells the perl parser to call parser() when it hits http keyword
  • http://twitter.com/statuses/show/6592721580.json example triggers this (perl has no problem naturally distinguishing “http” keyword from “http://”)
  • Get line of code in question (my $line = $self->get_linestr; )
  • parser() skips along the URL data following “http” ($self->offset) until it reaches a space, semicolon or a closing bracket (this covers “most” cases though comma could be an issue). This marks the end of the URL data
  • We now in essence change http://twitter.com/statuses/show/6592721580.json into http("http://twitter.com/statuses/show/6592721580.json")
  • And plonk the changed line back to the parser ($self->set_linestr($line);) and let it continue along its merry way
  • NB. http() sub was already imported into calling space and returns a LWP::Simple::get of the requested URL

 

Now is URLDSL useful in the real world? It can screw up syntax highlighting a bit (though WordPress highlighter coped extremely well, unlike Github :(

Its robust enough to cope with normal string interpolation:

my $id = '6592721580';
say decode_json( http://twitter.com/statuses/show/$id.json )->{text};

So perhaps I should upload it to CPAN? (earmarked for ACME:: perhaps!?). Anyone think this is useful little helper module then I wrap it up the next time I get a free moment.

The exercise as been fruitful in allowing me to get my head into the amazing Devel::Declare module for the first time.

I’ve used the Devel::Declare::Context::Simple class which simplifies things. Unfortunately there isn’t a POD on this yet but the main Devel::Declare docs nicely demonstrate the correct mechanics so its easy to adapt from this.

I also found this blog post by franck cuny to be extremely helpful. As was delving through the source code of other modules that used Devel::Declare

/I3az/

Keeping to a schedule

2009 December 13
tags:
by draegtun

When I made my Blogging Milestone post I decided to have a crack of writing Perl posts to a fixed schedule.

The Blogging Milestone post marked ten days since the previous post (ie. the Iron Man limit!). The following posts would continue to happen but reduced by a day each time. So next was 9 days later… then 8 days later… then 7 days later… until I reached zero days… my last post.

Phew… it did take a bit of effort to keep to a strict deadline but it is a good carrot & stick to keep you going!

Obviously I felt confident enough that I could do it (but not confident enough to announce that I was doing it!) and having lots of blog ideas written down + some partially composed ones does help ;-)

For all those posters that are doing Perl advent calendars at the moment I know what you must be going through and my hats off to you all.

/I3az/

to DO or not to DO, that is the question

2009 December 6
tags:
by draegtun

Following on from yesterdays post about do blocks, this is what I would normally do off the bat:

sub word_freq {
    my %words;
    $words{$_}++ for split /\s+/, lc $_[0];
    \%words;
}

Returning back a hash reference is both leaner and meaner ;-)

use List::Util qw(sum);

my $s = "The green hat is tHe twin of the green hat";

my $num_of_hats = word_freq( $s )->{ hat };   # word count just for 'hat'

# don't worry... always unique hashrefs returned:
my $hash_ref    = word_freq( $s );
my $hash_ref2   = word_freq( $s );       

# thus you can safely:
$hash_ref2->{green} = 100;
say "$hash_ref->{green} : $hash_ref2->{green}"; # => "2 : 100"    

# clean copy for those who prefer there hashes not to be hashrefs!
my %hash = %{ word_freq( $s ) };       

# returns ( 'is', 'of')
my @two_letter_words  = grep { length $_ == 2 } keys %{ word_freq( $s ) };

# number of "green" + "hat" == 4
my $green_plus_hat = sum @{ word_freq( $s ) }{ qw/green hat/ };

 

And what I probably wouldn’t do is:

use List::MoreUtils qw(uniq);

my $s = "The green hat is tHe twin of the green hat";

my %words = do {
    my @words = split /\s+/, lc $s;
    map {
        my $word = $_;
        $word => scalar grep { $_ eq $word } @words;
    } uniq @words
};

I actually prefer the code aesthetics of this but the extra cycle (grep) through @words pushes me towards the leaner hash counting solution. Horses for courses? ;-)

/I3az/