Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Thursday January 20, 2005
12:03 PM

A brief look at "real" OO

[ #22807 ]

I was thinking about putting together a talk about different programming styles and I decided to loosely translate the following snippet from Squeak (a free implementation of Smalltalk):

hello: times say: text
    (times > 100)
        ifTrue: [ Transcript show: 'You will get bored!']
        ifFalse: [1 to: times do: [:i | (Transcript show: text) cr]]

It's like some kind of bizarro mirror universe where everything looks OK until you peer closely at it. Since Squeak doesn't have if/then statements, what's really going on is the "greater than" comparison is actually a constructor and ifTrue and ifFalse are actually messages sent to the boolean object. It can choose to act on those messages or not and if it does, the code in the square brackets is evaluated (think "anonymous sub".) As a result, you really do have complete encapsulation and you could even reorder those messages if you so desired. In a traditional if/else statement, that's not always as easy.

To translate that into Perl, you might have the body of the method looking similar to this:

(Boolean->gt($times, 100))
    ->ifTrue(  sub {print "You will get bored!" } )
    ->ifFalse( sub {print $text for 1 .. $times } );

(Yes, I cheated with the range operator.)

And the relevent methods in Boolean might look like this:

package Boolean;

sub gt {
    my ($class, $num1, $num2) = @_;
    bless {
        true => ($num1 > $num2)
    } => $class;
}

sub ifTrue {
    my $self = shift;
    $self->{true} && shift->();
    return $self;
}

sub ifFalse {
    my $self = shift;
    ! $self->{true} && shift->();
    return $self;
}

1;

No if statements at all (though they're there in disguise.)

I'm not recommending this particular technique, but I did think it was a fascinating look at "pure OO" and its implications. This has proven very helpful to me as it taught me to take a closer look at how I use if statements. Much of my code is now conceptually cleaner due to finding a different way of thinking about the problem.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • That code example should be exhibit A in why I prefer Ruby over Smalltalk. That, and the image-based versus file-based issue. :)
    • Smalltalk syntax is like lisp syntax. It's deliberately small so that it can be parsed easily, and reflexive programming is easy.

      Squeak also includes a more traditional syntax if you choose to use it (most don't), but can still map the one syntax to the other, without even losing comment locations.

      Or, you can program in a tile-like environment in Morphic, which again builds Smalltalk methods from the tiles.

      The nice thing about Smalltalk is that it's a way of life, not a language. And every part of i

      --
      • Randal L. Schwartz
      • Stonehenge
  • This reminds me of something I did once on a long Metro-North ride home from NYC after reading a having read a paper on Smalltalk.

    #!/usr/bin/perl

    use strict;
    use warnings;

    use Test::More tests => 2;

    {
        package Boolean;

        use strict;
        use warnings;

        sub import {
            no strict 'refs';
            *{(caller())[0] . '::cond'} = \&cond;
        }

        sub cond (&) {
            my ($bloc

    --
    -stvn
    • Sweet! I would change two methods:

      sub isFalse {
          my ($self, $sub) = @_;
          ! $self->() && $sub->();
          return $self;
      }

      sub isTrue {
          my ($self, $sub) = @_;
          $self->() && $sub->();
          return $self;
      }

      Maybe I can slip this into production ... (no, I'm not serious.)

  • "Real" OO is Tlön [interglacial.com] -- a nice place to visit but I wouldn't want to think there.