Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Both Methods and Indexing for Objects?

Reply
Thread Tools

Both Methods and Indexing for Objects?

 
 
Veli-Pekka Tštilš
Guest
Posts: n/a
 
      07-31-2007
Hi,
I'd like to treat an object like an array but also provide methods for
accessing bits of the object state that aren't array-like. An example in
which this would be useful comes from Ruby, its regexp Match objects are
indexable like arrays for accessing back references, yet they also have
a nice interface via methods. Can Perl also do objects having both
methods and hash or array-like indexing?

I think I've found one possible solution, for arrays at least, after
reading Object Oriented Perl Ch 9.7 on tied objects. You could have a
constructor that returns a blessed ref to an underlying tied array,
which the user accesses like any array ref. As it is tied, its easy to
make the array read-only, for instance, if more restricted access is
desired. As the object made by the constructor is a blessed scalar the
user can also call methods on it. One way to handle the methods, and
also be able to store object state beside the array itself, is to
implement the tied array as a blessed hash behind the scenes. When a
method in which the non-array bits of the object are needed gets
called, you can dig up the underlying object behind the tied array via
tied.

To my surprise, at least in this simple script, both the array and the
object usage seem to be working OK. On second thought, putting the
methods dealing with tied variables in a separate package might have
been cleaner.

Are there easier ways of achieving essentially the same thing? Howabout
modules that would factor out the common bits even further, so that you
could state which hash member should have array-like access - in the
spirit of how Struct and MethodMaker automate matters. I'm still a bit
envious of Ruby's mixins and have been thinking of ways to implement
them in Perl, too.

And now the code, currently in a single file:

package TiedArray;
use strict; use warnings; use Tie::Array;
our @ISA = qw|Tie::Array|;

sub new
{ # Tie an array and bless the tied variable in $class.
my $class = shift;
my @array;
tie @array, $class, @_;
bless \@array, $class;
} # sub

sub TIEARRAY
{ # Implement as a hash with an array field.
my $self = { };
bless $self, shift;
$self->init(@_);
return $self;
} # sub

sub init
{ # Add fields and process arguments.
my $self = shift;
$self->{data} = shift;
} # sub

sub object
{ # Get the tied object given the tied variable $self.
my $self = shift;
tied @$self;
} # sub

# Pasted from Tie::StdArray with minor mods, as the array is in a hash.
sub FETCHSIZE { scalar @{$_[0]{array}} }
sub STORESIZE { $#{$_[0]{array}} = $_[1]-1 }
sub STORE { $_[0]->{array}[$_[1]] = $_[2] }
sub FETCH { $_[0]->{array}[$_[1]] }

# Methods for the underlying object:
sub data
{ # Accessor for the "data" hash member.
my $self = object(shift);
return $self->{data} unless @_;
$self->{data} = shift;
} # sub

sub size
{ # Getting the array size as a method.
my $self = shift;
return scalar @$self;
} # sub
1;

package main; # Some rather arbitrary tests.
my $array = TiedArray->new('stuff');
@$array[0 .. 1] = (qw|first second|);

print "Array: @$array\n";
print "Data: ", $array->data(), "\n";

$array->data('foo'),
push @$array, int(10 * rand) for 1 .. 4;

print "Array: @$array\n";
print "New data: ", $array->data(), "\n";

@$array = splice @$array, 1, 2;
print "Array: @$array\n";
print $array->size(), " elements.\n";

Thanks for any help in advance. I'm rather new to Perl OOP, especially
tied variables.

--
With kind regards Veli-Pekka Tštilš ((E-Mail Removed))
Accessibility, game music, synthesizers and programming:
http://www.student.oulu.fi/~vtatila
 
Reply With Quote
 
 
 
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      07-31-2007
Veli-Pekka Tštilš <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Hi,
> I'd like to treat an object like an array but also provide methods for
> accessing bits of the object state that aren't array-like. An example in
> which this would be useful comes from Ruby, its regexp Match objects are
> indexable like arrays for accessing back references, yet they also have
> a nice interface via methods. Can Perl also do objects having both
> methods and hash or array-like indexing?


You can overload de-referencing in your class. That won't make objects
look like arrays, but like array references, which may be good enough.

I've made up a Regex class that behaves a bit like what you describe.
After a match, an object can be used like an array ref that holds
the captured strings (with the entire match in array position 0).

Anno

-----------------------------------------------------------------------

my $r = Regex->new( '(.)(.)(.)');
$r->match( 'abc');

print "$r->[ $_]\n" for 1 .. 3;
print "@$r\n";


package Regex;

sub new {
my ( $class, $re) = @_;
bless { re => qr/$re/, capt => [] }, $class;
}

sub match {
my ( $r, $str) = @_;
@{ $r->{ capt} } = $str =~ /($r->{ re})/;
return scalar @{ $r->{ capt} };
}

use overload '@{}' => sub { shift()->{ capt} };
__END__
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic indexing (multi-dimensional-indexing) (probably my most important/valuable posting up to this date) Skybuck Flying C Programming 30 09-18-2011 11:29 PM
Indexing services under Windows XP SP2 - Can I disable MS Indexing Service to hasten Google's OR does Google Desktop uses this MS Indexing Service? ricardodefaria Computer Support 6 08-05-2007 04:14 AM
How much slower is dict indexing vs. list indexing? Emin Python 4 01-12-2007 02:40 PM
Indexing PDF's using MS Indexing Service C ASP General 3 10-17-2003 05:47 PM
Indexing PDF Files using MS Indexing Service C ASP .Net 0 10-17-2003 04:27 PM



Advertisments