Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Using closures to do data hiding in OO Perl
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  2 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Saurabh Hirani  
View profile  
 More options Jun 12 2009, 10:09 am
From: Saurabh Hirani <saurabh.hir...@gmail.com>
Date: Fri, 12 Jun 2009 07:09:44 -0700 (PDT)
Local: Fri, Jun 12 2009 10:09 am
Subject: Using closures to do data hiding in OO Perl
Reputation: 0

Hi guys,

I was just reading about closures on perl.com and read that Tom
Christiansen said that closures can be used to achieve data hiding in
OO perl. I thought about it and came up with an example to do that:

A module written without closures:
package Dinner;
use strict;
use warnings;

my $self = {};

sub new {
    my ($class) = @_;
    bless $self, $class;
    return $self;

}

sub washhands {
    my ($obj) = @_;
    $obj->{'handsclean'} = 1;
    return 1;

}

sub eatfood {
    my ($obj) = @_;
    if (exists $obj->{'handsclean'}) {
        print "\nYou washed your hands - eat all you want\n";
    } else {
        print "\nYou filthy animal!! Go wash your hands\n";
    }
    return 1;

}

1;

Its corresponding use:

#!/usr/bin/perl -w
use strict;
use Dinner;
my $dirtyeater = Dinner->new();
# I don't want to wash hands, I will just set the flag directly
# $dirtyeater->washhands;
$dirtyeater->{'handsclean'} = 1;
$dirtyeater->eatfood;

A Data::Dumper dump of $dirtyeater gives

$VAR1 = bless( { 'handsclean' => 1 }, 'Dinner' );

$dirtyeater can eat food if he knows what to change in the objects
data structure. I know that if you are playing with the object's ds
you do it at your own risk but I want to prevent the end user from
changing any object ds specific variables. So I write another module
called Dinnerclosure.pm:

package Dinnerclosure;
use strict;
use warnings;

sub new {
    my ($class) = @_;
    my $self = {};
    my $selfmirage = {};
    $selfmirage->{'washhands'} = sub {
                                   washhands($self);
                                 };
    $selfmirage->{'eatfood'} = sub {
                                   eatfood($self);
                               };
    bless $selfmirage, $class;
    return $selfmirage;

}

sub washhands {
    my ($obj) = @_;
    $obj->{'handsclean'} = 1;
    return 1;

}

sub eatfood {
    my ($obj) = @_;
    if (exists $obj->{'handsclean'}) {
        print "\nYou washed your hands - eat all you want\n";
    } else {
        print "\nYou filthy animal!! Go wash your hands\n";
    }
    return 1;

}

1;

The testcode:

#!/usr/bin/perl -w
use strict;
use Dinnerclosure;
my $cleaneater = Dinnerclosure->new();
# comment this line and uncomment the next, but it won't wash hands
$cleaneater->{'washhands'}->();
#$cleaneater->{'handsclean'} = 1;
$cleaneater->{'eatfood'}->();
print Dumper $cleaneater;

$dirtyeater cannot change the 'cleanhands' flag. If he does, he will
be changing the $selfmirage hashref which does not decide cleanliness,
$self does. And $dirtyeater cannot access $self because the object is:

$VAR1 = bless( {
                 'eatfood' => sub { "DUMMY" },
                 'washhands' => sub { "DUMMY" }
               }, 'Dinnerclosure' );

Advantages:

   1. You have to wash hands before eating. :) - to generalize - you
can only call subs to manipulate data.There is no other choice.
   2. $self and $selfmirage are lexically scoped within the new sub.
They don't even have to be declared at top of package before any subs
in case of Dinner.pm - better lexical scoping
   3. The end user does not see any object innards in the ds

WYDSIWYDG - What you don't see is what you don't get :)

-- Saurabh


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Remi Mustapha  
View profile  
 More options Jun 12 2009, 1:47 pm
From: Remi Mustapha <rmusta...@gmail.com>
Date: Fri, 12 Jun 2009 10:47:48 -0700
Local: Fri, Jun 12 2009 1:47 pm
Subject: Re: Using closures to do data hiding in OO Perl

Thanks for sharing

On Fri, Jun 12, 2009 at 7:09 AM, Saurabh Hirani <saurabh.hir...@gmail.com>wrote:

--
rafiu mustapha

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2010 Google