Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Prototypes/Parameters to a Function/Sub-Routine

Reply
Thread Tools

Prototypes/Parameters to a Function/Sub-Routine

 
 
O. Olson
Guest
Posts: n/a
 
      08-01-2007
Hi,
I would like to know if it is possible to enforce the number and type
of the parameters in a function prototype. Assuming that a person does
not circumvent the prototypes using &.

I have tried the following that tries to say that the function
printScalar () should only accept a single Parameter. This does not
work i.e. does not compile.

# This function would print the time variable passed
sub printScalar(my $num)
{
print "$num";
}


I have looked at perlsub at http://perldoc.perl.org/perlsub.html - and
I am not sure if the answer to my Question is NO.

This would be of more importance when I am working with Objects i.e.
to ensure that the reference passed, is an object of a certain class.

Thanks a lot.
O.O.

 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      08-01-2007
On Aug 1, 11:41 am, "O. Olson" <(E-Mail Removed)> wrote:
> I would like to know if it is possible to enforce the number and type
> of the parameters in a function prototype. Assuming that a person does
> not circumvent the prototypes using &.


That is supposed to be the idea behind subroutine prototypes, yes.
But they don't work correctly.

> I have tried the following that tries to say that the function
> printScalar () should only accept a single Parameter. This does not
> work i.e. does not compile.
>
> # This function would print the time variable passed
> sub printScalar(my $num)


What part of perlsub gave you the idea that was valid syntax?

> {
> print "$num";


perldoc -q quoting

> }
>
> I have looked at perlsub athttp://perldoc.perl.org/perlsub.html- and
> I am not sure if the answer to my Question is NO.
>
> This would be of more importance when I am working with Objects i.e.
> to ensure that the reference passed, is an object of a certain class.


What you are trying to do is:

sub printScalar($) {
my $num = shift;
print $num;
}

Doing that, when someone calls your subroutine with something other
than one scalar value, they will get a syntax error:

$ perl -le'
sub printScalar($) {
my $num = shift;
print $num;
}
printScalar(10, 20);
'
Too many arguments for main:rintScalar at -e line 6, near "20)"
Execution of -e aborted due to compilation errors.


However, as I said, prototypes do NOT work correctly. For example,
you would probably expect this to give a similar error, wouldn't you?
$ perl -le'
sub printScalar($) {
my $num = shift;
print $num;
}
my @nums = (10, 20);
printScalar(@nums);
'

But instead, this program executes just fine, and displays the number
"2". Why? Because you told the subroutine to take a scalar
argument. The user passed an array. So Perl "helpfully" took that
array, and evaluated it in scalar context, and an array in scalar
context gives its size.

Similarly, you'd probably expect this to return an error that a list
is required:

$ perl -le'
sub printArray(@) {
my @nums = @_;
print for @nums;
}
printArray();
'

But this program executes just fine. Because an "empty" list is still
a list. We could go on and on. Say you want a subroutine to take two
scalars:
sub printBoth($$);
but if a user calls it like so:
my @mixmax = (5, 10);
printBoth(@minmax);
Perl will throw an error, even though the array does indeed contain
two scalars.


End result, you can't enforce this type of checking at compile time.
You have to do it manually at runtime.

sub printObject {
@_ == 1 or
croak "Invalid number of arguments passed to printObject";
my $obj = shift;
ref $obj or
croak "Argument to printObject is not a reference";
UNIVERSAL::isa($obj, "MyClass") or
croak "Argument to printObject is not a MyClass";
#etc . . .
}

Paul Lalli

 
Reply With Quote
 
 
 
 
Klaus
Guest
Posts: n/a
 
      08-01-2007
On Aug 1, 5:41 pm, "O. Olson" <(E-Mail Removed)> wrote:
> Hi,
> I would like to know if it is possible to enforce the number and type
> of the parameters in a function prototype. Assuming that a person does
> not circumvent the prototypes using &.
>
> I have tried the following that tries to say that the function
> printScalar () should only accept a single Parameter. This does not
> work i.e. does not compile.
>
> # This function would print the time variable passed
> sub printScalar(my $num)
> {
> print "$num";
>
> }
>
> I have looked at perlsub athttp://perldoc.perl.org/perlsub.html- and
> I am not sure if the answer to my Question is NO.


Looking at the article "Far More Than Everything You've Ever Wanted to
Know about Prototypes in Perl" by Tom Christiansen:
http://library.n0i.net/programming/p...fm_prototypes/
I would say the answer to your question is probably no.

> This would be of more importance when I am working with Objects i.e.
> to ensure that the reference passed, is an object of a certain class.


You can test the package name of an object, see perldoc -f ref

--
Klaus

 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      08-01-2007
On Wed, 01 Aug 2007 08:41:36 -0700, "O. Olson" <(E-Mail Removed)>
wrote:

> I would like to know if it is possible to enforce the number and type
>of the parameters in a function prototype. Assuming that a person does


No. Perl 5 does not have a type system. Perl 6 will, but it will still
be optional.

>I have tried the following that tries to say that the function
>printScalar () should only accept a single Parameter. This does not
>work i.e. does not compile.
>
># This function would print the time variable passed
>sub printScalar(my $num)


In fact that's not a valid syntax. You want

sub printScalar ($) { ... }

instead.

>This would be of more importance when I am working with Objects i.e.
>to ensure that the reference passed, is an object of a certain class.


You're out of luck! Prototypes do not work at all when subs are called
as methods. Still talking 'bout Perl 5, of course...


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,
 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      08-01-2007
On Wed, 01 Aug 2007 09:49:14 -0700, Paul Lalli <(E-Mail Removed)>
wrote:

>Similarly, you'd probably expect this to return an error that a list
>is required:
>
>$ perl -le'
>sub printArray(@) {
> my @nums = @_;
> print for @nums;
>}
>printArray();
>'
>
>But this program executes just fine. Because an "empty" list is still
>a list.


In fact this is perfectly fine, if you ask me, and not a good example
of prototypes failing. I'm not really sure but I think that even Perl
6's powerful signatures do not provide means to specify that a list to
be passed must have a specific size, or even more simply that it is
non empty.


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,
 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      08-01-2007
On Aug 1, 1:56 pm, Michele Dondi <(E-Mail Removed)> wrote:
> On Wed, 01 Aug 2007 09:49:14 -0700, Paul Lalli <(E-Mail Removed)>
> wrote:
>
> >Similarly, you'd probably expect this to return an error that a list
> >is required:

>
> >$ perl -le'
> >sub printArray(@) {
> > my @nums = @_;
> > print for @nums;
> >}
> >printArray();
> >'

>
> >But this program executes just fine. Because an "empty" list is still
> >a list.

>
> In fact this is perfectly fine, if you ask me, and not a good example
> of prototypes failing.


Perhaps not, but I think it is a decent example of prototypes not
doing what someone new to Perl programming would *expect* them to do.

Paul Lalli

 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      08-02-2007
On Wed, 01 Aug 2007 12:19:45 -0700, Paul Lalli <(E-Mail Removed)>
wrote:

>> >But this program executes just fine. Because an "empty" list is still
>> >a list.

>>
>> In fact this is perfectly fine, if you ask me, and not a good example
>> of prototypes failing.

>
>Perhaps not, but I think it is a decent example of prototypes not
>doing what someone new to Perl programming would *expect* them to do.


I'm thinking of it and I'm fairly sure that it's not the case, and in
particular that as a newbie I wouldn't have expected so. But then it's
probably because we tend to project our own way to see things on the
others too.


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,
 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      08-02-2007
O. Olson <(E-Mail Removed)> wrote in comp.lang.perl.misc:

[prototype question, has been answered]

> This would be of more importance when I am working with Objects i.e.
> to ensure that the reference passed, is an object of a certain class.


It is usually an indication of a design error if a method has to
care about the class an object comes from. If an object *can* invoke
a method (through inheritance, for instance) the method should be able
to handle it.

Anno
 
Reply With Quote
 
O. Olson
Guest
Posts: n/a
 
      08-03-2007
Thanks Paul for your detailed discussion.

On Aug 1, 6:49 pm, Paul Lalli <(E-Mail Removed)> wrote:
> What part of perlsub gave you the idea that was valid syntax?
>


No, I did not mean to say that I got this idea from perlsub - just
that I wanted to do something like this - but this was not available
in Perlsub. Anyway now I got the idea.

> UNIVERSAL::isa($obj, "MyClass") or
> croak "Argument to printObject is not a MyClass";



I think this is what I wanted i.e. a way to check if an object is of a
certain class.

Thanks again,
O.O.




 
Reply With Quote
 
O. Olson
Guest
Posts: n/a
 
      08-03-2007
On Aug 1, 7:26 pm, Michele Dondi <(E-Mail Removed)> wrote:
>
> No. Perl 5 does not have a type system. Perl 6 will, but it will still
> be optional.


Thanks Michele. I think would wait for Perl 6 - Whenever that's going
to come out.
O.O.


 
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




Advertisments