[29326] in Perl-Users-Digest
Perl-Users Digest, Issue: 570 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Jun 24 21:10:22 2007
Date: Sun, 24 Jun 2007 18:09:15 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sun, 24 Jun 2007 Volume: 11 Number: 570
Today's topics:
Re: FAQ 1.6 What is perl6? <brian.d.foy@gmail.com>
Passing function references in the constructor koszalekopalek@interia.pl
Re: Passing function references in the constructor <bik.mido@tiscalinet.it>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Sun, 24 Jun 2007 15:36:21 -0500
From: brian d foy <brian.d.foy@gmail.com>
Subject: Re: FAQ 1.6 What is perl6?
Message-Id: <240620071536218163%brian.d.foy@gmail.com>
In article <bnqq73p09mn474u21849qqva8evfi7npqm@4ax.com>, Michele Dondi
<bik.mido@tiscalinet.it> wrote:
> On Sat, 23 Jun 2007 11:40:17 -0500, brian d foy
> <brian.d.foy@gmail.com> wrote:
>
> >> >1.6: What is perl6?
> >>
> >> Isn't this a partial duplicate of "1.4: What are perl4, perl5, or
> >> perl6?"
> >>
> >> How about merging the two entries?
> >
> >I'll have to think about that. We might not need the ones for 4 or 5 :)
>
> Also, how 'bout the spelling?
Yes, I should capitalize Perl and put a space before the version
number. I'll look through the FAQ during YAPC and see where this needs
improvement. :)
--
Posted via a free Usenet account from http://www.teranews.com
------------------------------
Date: Sun, 24 Jun 2007 13:52:35 -0700
From: koszalekopalek@interia.pl
Subject: Passing function references in the constructor
Message-Id: <1182718355.585496.129750@n60g2000hse.googlegroups.com>
Hello,
I would like to create a number of objects of the same class (mypack)
and specify a reference to a function in the constructor. I would like
to
let the module user either use a predefined function (e.g. test1)
provided in the class or let him write his own function and provide
a reference to it in the constructor.
The example below does just that.
I create object $obj1 of class mypack and use a predefined sub test1.
Then I create $obj2 and pass a reference to a custom function
customtest.
The problem is that the two functions
$obj1->riddle (1, 2, 3);
and
$obj2->riddle (1, 2, 3);
receive different arguments depending on where they come from.
The first argument passed to the function test1 is the name of the
class (and then comes the number, i.e. 1). If it is customtest, it
does
not get the name of the class.
This is the output of the attached program:
---- test1 args ----
mypack
1
---- customtest args ----
1
2
What would be the most elegant way to tackle this problem? I'd
rather
not shift arguments in test1 or do anything like that. Maybe there
is
a better way to pass function references in the constructor?
#!/usr/bin/perl
{
package mypack;
sub new {
my $class = shift;
$self = { @_ };
bless $self, $class;
return $self;
};
sub riddle {
my $self = shift;
my $testref = \&test;
my $testref = $self->{fun};
&$testref (@_);
};
sub test1 {
print "---- test1 args ----\n";
print @_[0], "\n";
print @_[1], "\n";
};
};
sub customtest {
print "---- customtest args ----\n";
print @_[0], "\n";
print @_[1], "\n";
}
my $obj1 = mypack->new(
fun => sub { mypack->test1 (@_) }
);
$obj1->riddle (1, 2, 3);
my $obj2 = mypack->new(
fun => \&customtest
);
$obj2->riddle (1, 2, 3);
------------------------------
Date: Mon, 25 Jun 2007 00:46:05 +0200
From: Michele Dondi <bik.mido@tiscalinet.it>
Subject: Re: Passing function references in the constructor
Message-Id: <7brt73toslg1i9kbbh3v9m083mh68br82k@4ax.com>
On Sun, 24 Jun 2007 13:52:35 -0700, koszalekopalek@interia.pl wrote:
>I would like to create a number of objects of the same class (mypack)
>and specify a reference to a function in the constructor. I would like
>to
>let the module user either use a predefined function (e.g. test1)
>provided in the class or let him write his own function and provide
>a reference to it in the constructor.
So far, so fine: just use something like
my ($class, $code)=@_;
# ...
$code=\&test1 unless 'CODE' eq ref $code;
>The problem is that the two functions
> $obj1->riddle (1, 2, 3);
>and
> $obj2->riddle (1, 2, 3);
These are not functions, but methods.
>receive different arguments depending on where they come from.
?!?
>The first argument passed to the function test1 is the name of the
>class (and then comes the number, i.e. 1). If it is customtest, it
>does
It depends on how you're calling it. Do you expect it to be called as
a plain sub or as a method? Just take the decision first, make that an
API and stick with it.
>What would be the most elegant way to tackle this problem? I'd
>rather
>not shift arguments in test1 or do anything like that. Maybe there
Why not? It just depends, again, on how you intend to call it.
> sub new {
> my $class = shift;
> $self = { @_ };
> bless $self, $class;
> return $self;
> };
The constructor doesn't seem to handle a subref passed to it in any
particular way. Hence no sign of the defaulting to test1() which you
hinted to.
>
> sub riddle {
> my $self = shift;
> my $testref = \&test;
> my $testref = $self->{fun};
Huh?!? Under warnings this will also issue a... well, warning! Why the
double assignment anyway?
> &$testref (@_);
Whatever, if $testref contains a subref (but then you should really
check somewhere) and if you call it like that, or as in
$testref->(@_); # preferred!
then you have a normal sub call, i.e. no class name or object passed
in as the first argument. Alternatively, you can do:
$self->$testref(@_);
and then it will be called like a method on $self. Whether you want
this, or the other way round as I said is something you must choose in
advance, and then stay consistent.
>my $obj1 = mypack->new(
> fun => sub { mypack->test1 (@_) }
>);
Huh?!? You're passing in an anonymous sun which *in its body* (hence
the problem has NOTHING to do with "passing function references in the
constructor"!) will call your package's test1() as a *method*. You can
use the fully referenced name instead, if you really want to do so:
fun => sub { mypack::test1 (@_) }
But you probably meant just
fun => \&mypack::test1
All in all, the simplest variation of your original code (also fixing
some stylistic issues, what's with all those semicolons?) that still
does no (good) checks, etc. is:
#!/usr/bin/perl
use warnings;
use strict;
{
package Mypack; # all lowercase ones are reserved for pragmatas
sub new {
my $class = shift;
bless { @_ }, $class;
}
sub riddle {
my $self = shift;
($self->{fun} || \&test1)->(@_);
}
sub test1 { print "test1 args: [@_]\n" }
}
my $obj1 = Mypack->new; # defaulting to test1
$obj1->riddle(1, 2, 3);
my $obj2 = Mypack->new( fun => sub { print "customtest args: [@_]\n"
} );
$obj2->riddle(1, 2, 3);
__END__
Alternatively, make riddle() into
sub riddle {
my $self = shift;
my $code = $self->{fun} || \&test1;
$self->$code(@_);
}
And see what happens. For the last time: just choose what you like
best.
After much thinking... I suspect smell of XY problem here. See e.g.
<http://perlmonks.org/?node=XY+problem>.
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
.'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc. For subscription or unsubscription requests, send
#the single line:
#
# subscribe perl-users
#or:
# unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 570
**************************************