I just applied the autobox patch and started playing with it. Autoboxing is controversial, but it's rather interesting. Autoboxing is used in Java, C# and Ruby. It allows you to call methods on built-in datatypes, including literals!

The patch is small, but it does require you to compile Perl from source (sorry, folks!). You can read the documentation for more information, but basically, you create a class for your data type and then you can call methods. For example, let's say you want to implement this:

use autobox; my @nums = 1->to(10); my @reverse = 10->to(1);

One way of doing that would be to create the following SCALAR class:

package SCALAR; + + sub to { my ($from, $to) = @_; return $from > $to ? (reverse $to .. $from) : ($from .. $to); } 1;

It looks nifty, but it seems to have some annoying limitations:

  @nums->sort;

That looks good, but you might expect that you would create this in the ARRAY package (as you would with array refs). In this case, however, you get the error:

Can't locate object method "sort" via package "SCALAR" at ./test.pl line 30.

Having an array call methods in a scalar class is not intuitive.

Finally, I spent a couple of minutes implementing a Schartzian Transform:

my @data = ( 'test12-05-2003this', 'test11-05-2003this', 'test12-06-2003this', 'test12-05-2000this', ); @data = schwartzian(@data); print Dumper \@data; + + sub schwartzian { # do I *really* have to use strings here? :( my $result = [@_] ->map ('[$_,main::get_date($_)]') ->sort('$a->[1] <=> $b->[1]') ->map ('$_->[0]'); return @$result; } + + sub get_date { my ($month,$day,$year) = shift =~ /(\d+)-(\d+)-(\d+)/; return "$year$month$day"; }

And the supporting package:

package ARRAY; + + sub grep { [eval "grep {$_[1]} \@{\$_[0]}"] } sub map { [eval "map {$_[1]} \@{\$_[0]}"] } sub sort { [eval "sort {$_[1]} \@{\$_[0]}"] } + + # reverse is not used in this example sub reverse { [reverse @{$_[0]} ] } 1;

I'm not sure how to clean up the Schwartzian Transform with this code, so please take a swing at it. Passing strings of code is ugly.

Autoboxing seems kind of nifty, but I'm not sure if it gains enough to be worthwhile (though I thought it was cool at first). If you haven't already, read through the "controversial" thread above and then let me know what you think. Do you like autoboxing or not? What would you use it for, if anything. Code samples would be great.

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re: Autoboxing: Yes or No?
by BrowserUk (Patriarch) on Jan 01, 2004 at 01:06 UTC

    In terms of gain, I see little or no gain by using this 'autoboxing' (sounds like the M25 in rush hour!:)

    I like OO, but I see no benefit (and considerable overhead) in hiding the standard apis behind pseudo-OO syntax. If it came built-in that way, that's fine, but adding two layers of overhead just to achieve a different syntax doesn't ring my bells at all.

    I'm not sure how to clean up the Schwartzian Transform with this code...

    Perhaps the obvious, though somewhat controversial method of avoiding the code strings would be to use a prototype and pass code blocks. It would save several evals. Even so, the code will run about 4 times slower than coding the ST in the standard way, and given that the vast majority of the syntax has now become parameters to a sub (whether as strings or anon. code blocks), where is the benefit?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

Re: Autoboxing: Yes or No?
by Anonymous Monk on Jan 01, 2004 at 01:10 UTC
    Autoboxing is used in Java, C# and Ruby.

    I don't think you should be including Ruby, which has no non-object primitives to autobox.

    Autoboxing seems kind of nifty, but I'm not sure if it gains enough to be worthwhile (though I thought it was cool at first). If you haven't already, read through the "controversial" thread above and then let me know what you think.

    It is the kind of thing that can look good on the surface, but instead of bringing any real unification of objects and primitives, it just brings inconsistencies to your code.

      Exactly. Ruby shouldn't be included. As for the rest, Linus Torvalds put it well on a different topic:
      ...You've then superglued the broken parts together and said "if you look at it from the right angle you cannot SEE the cracks".

      But the cracks ARE THERE! They make the system more complex internally, and even when you don't see the cracks you may notice that the thing doesn't quite stand up straight.

      If you want everything to work as an object, then you really need to start with it done right. Because if you don't and try to reverse-engineer things, then you wind up with something like tie - it looks cool but never quite works properly when you push it.
Re: Autoboxing: Yes or No?
by Corion (Patriarch) on Jan 01, 2004 at 17:08 UTC

    For me, autobox is just that, a cool hack. It dosen't gain much, because all changes you're making are global changes, much like injecting methods into UNIVERSAL, which is not a good idea as well.

    The one thing autoboxing buys you would be fancy syntax, but I don't see where the fancy syntax would make stuff nicer to read, and I imagine ugly/obfuscated stuff like this:

    1->'1'(1 => 1)

    The price we'd pay for autoboxing would be global class pollution, as people would wildly add methods to SCALAR, ARRAY and HASH, with all the name conflicts that usually happen then.

    Class creation under Perl is only a bless away, and if you need special behaviour of your primitive datatypes, bless them into a class - Perl is not Java, where a class must reside in a different file, that is appropriately named, and we don't even need to decide on the class name at implementation name. If you want fancy stringification etc., overload buys us that, the only thing that's ugly to implement is fancy HASH or ARRAY semantics, which could be bought by tie (although, there is a price to pay).

    For specialized small projects, clever autoboxing could simplify the code, but for anything over 100 lines, the special behaviour is better moved into its own class IMHO.

    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
Re: Autoboxing: Yes or No?
by Abigail-II (Bishop) on Jan 01, 2004 at 13:40 UTC
    Do you like autoboxing or not? What would you use it for, if anything.

    Apart from some syntactical sugar, I don't see any benefit from autoboxing. And since it's sugar that doesn't appeal to me at all, I won't use it.

    Abigail

Re: Autoboxing: Yes or No?
by oha (Friar) on Jan 01, 2004 at 18:32 UTC
    maybe i didn't understood, but i see no reason to use schwartzian transformation here. am i wrong?

      Whether or not a Schwartzian Transform was warranted was beside the point. I was just using that to demonstrate autoboxing. Though I have to confess that, while really cool, I can't see any use for autoboxing. I was hoping that someone would whip up a killer app and convince a sceptical world that they can't do without this, but I doubt I'll see that happen (and curiously, even in the arguments that I've seen in favor of autoboxing, I've not seen anyone post code).

      Cheers,
      Ovid

      New address of my CGI Course.

        OK, so this may not be a "killer app", but one feature of autoboxing can be really a time-saver: methods on undef

        I like chaining methods, and often I am only interested in the result of the whole chain. For example when navigating an XML document: $elt->first_child->text or $doc->root->last_child( 'section')->first_child( 'title')->att( 'num'). If one of the calls fails, than I am happy with undef being returned. I just don't like having to test every single method call. Which is often what I have to do, or the program dies when it tries calling a method on undef.

        None of the possible alternatives seems to be as convenient as autoboxing undef, the closest in convenience, but I would guess at a higher performance price, being by returning a pre-defined object instead of undef in case of failure and overloading the boolean-ification of the object.