Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Prototypes/Parameters to a Function/Sub-Routine (http://www.velocityreviews.com/forums/t904024-prototypes-parameters-to-a-function-sub-routine.html)

O. Olson 08-01-2007 03:41 PM

Prototypes/Parameters to a Function/Sub-Routine
 
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.


Paul Lalli 08-01-2007 04:49 PM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
On Aug 1, 11:41 am, "O. Olson" <olson_...@yahoo.it> 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::printScalar 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


Klaus 08-01-2007 04:57 PM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
On Aug 1, 5:41 pm, "O. Olson" <olson_...@yahoo.it> 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


Michele Dondi 08-01-2007 05:26 PM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
On Wed, 01 Aug 2007 08:41:36 -0700, "O. Olson" <olson_ord@yahoo.it>
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,

Michele Dondi 08-01-2007 05:56 PM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
On Wed, 01 Aug 2007 09:49:14 -0700, Paul Lalli <mritty@gmail.com>
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,

Paul Lalli 08-01-2007 07:19 PM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
On Aug 1, 1:56 pm, Michele Dondi <bik.m...@tiscalinet.it> wrote:
> On Wed, 01 Aug 2007 09:49:14 -0700, Paul Lalli <mri...@gmail.com>
> 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


Michele Dondi 08-02-2007 09:27 AM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
On Wed, 01 Aug 2007 12:19:45 -0700, Paul Lalli <mritty@gmail.com>
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,

anno4000@radom.zrz.tu-berlin.de 08-02-2007 11:50 AM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
O. Olson <olson_ord@yahoo.it> 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

O. Olson 08-03-2007 02:50 AM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
Thanks Paul for your detailed discussion.

On Aug 1, 6:49 pm, Paul Lalli <mri...@gmail.com> 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.





O. Olson 08-03-2007 02:52 AM

Re: Prototypes/Parameters to a Function/Sub-Routine
 
On Aug 1, 7:26 pm, Michele Dondi <bik.m...@tiscalinet.it> 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.




All times are GMT. The time now is 04:51 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.