Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > returning references, etc.

Reply
Thread Tools

returning references, etc.

 
 
Sherm Pendley
Guest
Posts: n/a
 
      10-05-2005
Bertilo Wennergren <(E-Mail Removed)> writes:

> I've tried to do things like you say, calling subroutines without "&", but
> lately I've had the compiler sometimes complain about the wrong number of
> arguments (which was never true!), and I've found that the only solution
> was to add a "&" to the subroutine call.


When your car's "check engine" light comes on, would you consider the problem
solved if the mechanic simply disconnected the light without diagnosing the
cause of the problem? That's what you're doing here.

Using "&" disables prototype checking. That's where you declare a sub as
taking a specific number and type of arguments, like so:

sub foo($$) {
return "howdy\n";
}

print foo;

When I run this, I get:

test.pl:10: Not enough arguments for main::foo near "foo;"

Which is clear enough - I've asked for two arguments, and not supplied any.

The correct solution to this is to prototype the correct number of arguments,
or if you'll be passing different numbers of arguments, just omit the proto-
type completely:

sub foo {
return "howdy\n";
}

print foo;

This produces the expected "howdy".

While there are occasionally perfectly good reasons to silence a warning that
you do understand, silencing a warning that you don't understand is never a
good idea.

Have a look at "perldoc perlsub" for details about declaring and calling
Perl functions.

sherm--

--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
 
Reply With Quote
 
 
 
 
Bertilo Wennergren
Guest
Posts: n/a
 
      10-05-2005
A. Sinan Unur skribis:

> Bertilo Wennergren <(E-Mail Removed)>


>> I've tried to do things like you say, calling subroutines without "&",
>> but lately I've had the compiler sometimes complain about the wrong
>> number of arguments


> I would be interested to see how you get perl to complain about an
> incorrect number of arguments to a sub.


Me too.

> Are you using prototypes?


Not at all.

--
Bertilo Wennergren <http://bertilow.com>
 
Reply With Quote
 
 
 
 
Bertilo Wennergren
Guest
Posts: n/a
 
      10-05-2005
Tad McClellan:

> Bertilo Wennergren <(E-Mail Removed)> wrote:


>> This seems to happen most often in
>> regular expressions (with an "e" switch),


> There are no subroutines involved with regular expressions,
> so you must have entered the Twilight Zone or something.


I meant subroutine calls used in the replacement part of a substitution.
Sorry about the hazy (read "wrong") terminology:

$foo =~ s/what(ever)/subroutine($1)/ge;

Here's a stupid example:

#!/usr/bin/perl
use strict;
my $text = 'barbarian';
$text =~ s/(a[rn])/subroutine($1)/ge;
print "$text\n";
sub subroutine() {
my $t = shift;
if ($t =~ /r/) {
$t =~ s/a/r/g;
} elsif ($t =~ /n/) {
$t =~ s/a/n/g;
}
return $t;
}

This works (prints "brrbrrinn\n"), but sometimes when I do stuff like that
(not using any prototyping!), perl complains about the wrong number of
arguments making me scratch my head.

Actually, if I add "-w" to the first line of the above, I do get a weird
warning about prototypes:

main::subroutine() called too early to check prototype at test.pl line 5.

Why do I get that warning? It should mean that I've called a function that
has a prototype before the parser saw a definition or declaration for it.
But I haven't used any prototyping in that code. (Or I've completely
misunderstood what prototyping is. That should be no wonder, since I never
- consciously - use prototyping.)

> We will be able to answer your question when you come up with one,
> until then there is no telling...


You're right of course. I'll try to whip up something that actually makes
the compiler complain. That's a bit hard though, since I've never
understood the circumstances.

--
Bertilo Wennergren <http://bertilow.com>
 
Reply With Quote
 
Bertilo Wennergren
Guest
Posts: n/a
 
      10-05-2005
Sherm Pendley:

> Bertilo Wennergren <(E-Mail Removed)> writes:


>> I've tried to do things like you say, calling subroutines without "&",
>> but lately I've had the compiler sometimes complain about the wrong
>> number of arguments (which was never true!), and I've found that the only
>> solution was to add a "&" to the subroutine call.


> When your car's "check engine" light comes on, would you consider the
> problem solved if the mechanic simply disconnected the light without
> diagnosing the cause of the problem? That's what you're doing here.


I know. That's why I'm asking now. I've tried (using the documentation,
googling, etc) to find out what I'm actually doing wrong. But so far I've
gotten nowhere.

> Have a look at "perldoc perlsub" for details about declaring and calling
> Perl functions.


OK. Suddenly I lightbulb. I'm in the habit of writing my subroutines like
this:

sub whatever() { ... }

Now I realise that's probably a bad habit picked up from writing Javascript
code. If I understand right, putting in the parentheses actually means
using prototyping. I didn't know that. I thought putting dollar signs etc
inside the parentheses did that. This explains almost everything. I should
have used "-w" a lot more (hangs head in shame...).

But now I don't understand why I only get a warning (most of the time).
Shouldn't I get a syntax error if I call such a subroutine using one or
more arguments? Doesn't "sub whatever()" mean that I'm prototyping that sub
to use exactly zero arguments?

#!/usr/bin/perl -w
use strict;
my $text = 'barbarian';
$text = subroutine($text);
print "$text\n";
sub subroutine {
my $t = shift;
# whatever
return $t;
}

No syntax error, only a warning.

Anyway I'll stop using the useless parentheses. Thanks for your help!

--
Bertilo Wennergren <http://bertilow.com>
 
Reply With Quote
 
Bertilo Wennergren
Guest
Posts: n/a
 
      10-05-2005
Sherm Pendley:

> Bertilo Wennergren <(E-Mail Removed)> writes:


>> sub subroutine() {
>> [...]


>> This works (prints "brrbrrinn\n"), but sometimes when I do stuff like
>> that (not using any prototyping!)


> The above *is* using a prototype - it's specified as taking no arguments.


Yes, I just found out what my use of parentheses actually means. I use them
only as a bad habit picked up from Javascript. I had no idea I was using
prototyping. (Never actually wanting to use prototyping, I never really
delved much into the subject.) I'll stop doing that now, of course.

But I don't understand why I only sometimes get an actual error when I call
such a badly declarated with an argument. It probably has something to do
with my always putting all the subroutines at the end of the code, but I
still can't make the whole puzzle fit.

--
Bertilo Wennergren <http://bertilow.com>
 
Reply With Quote
 
John Bokma
Guest
Posts: n/a
 
      10-05-2005
Bertilo Wennergren <(E-Mail Removed)> wrote:

> But I don't understand why I only sometimes get an actual error when I
> call such a badly declarated with an argument. It probably has
> something to do with my always putting all the subroutines at the end
> of the code, but I still can't make the whole puzzle fit.


perldoc -f sub might be a great help instead of guessing, experimenting,
etc. The worst method of learning to program is trial and error: not
reading documentation and using "experience" from other languages,
especially if the latter is obtained in exactly the same way (which is
often the case, somehow).

--
John Small Perl scripts: http://johnbokma.com/perl/
Perl programmer available: http://castleamber.com/
I ploink googlegroups.com

 
Reply With Quote
 
Sherm Pendley
Guest
Posts: n/a
 
      10-05-2005
Bertilo Wennergren <(E-Mail Removed)> writes:

> But I don't understand why I only sometimes get an actual error when I call
> such a badly declarated with an argument. It probably has something to do
> with my always putting all the subroutines at the end of the code, but I
> still can't make the whole puzzle fit.


That's exactly it. The compiler starts at the top of your code and compiles
to the end, so when it gets to a function call it's only aware of whatever
prototypes have been declared above the call. But that's just a warning, not
an error. It can still call the function, it just can't verify that the number
and type of arguments are correct.

For example, take this script:

#!/usr/bin/perl

use warnings;
use strict;

# foo() has not been prototyped at this point, so arguments aren't checked
print foo();

# Oops, foo() has a prototype now - but it's too late to go back and check
# that earlier call to foo().
sub foo() {
return "Howdy\n";
}

In addition to the expected "Howdy", it produces the following warning:

test.pl:6: main::foo() called too early to check prototype

You'll get a much more thorough description of the problem, and suggested
solutions, if you do "use diagnostics" instead of "use warnings".

There are two ways to deal with that. You could declare the sub above the
rest of the code. Or, you could forward declare the sub, like this:

#!/usr/bin/perl

use warnings;
use strict;

# Forward declare the subroutine foo() - define it later
sub foo();

print foo();

sub foo() {
return "Howdy\n";
}

If you've done any C/C++ programming, you'll feel right at home with this
declaration/definition split. If you've only done Java before this, you'll
find it bizarre beyond words.

sherm--

--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
 
Reply With Quote
 
Bertilo Wennergren
Guest
Posts: n/a
 
      10-05-2005
Sherm Pendley:

> Bertilo Wennergren <(E-Mail Removed)> writes:


>> But I don't understand why I only sometimes get an actual error when I
>> call such a badly declarated with an argument. It probably has something
>> to do with my always putting all the subroutines at the end of the code,
>> but I still can't make the whole puzzle fit.


> That's exactly it. The compiler starts at the top of your code and
> compiles to the end, so when it gets to a function call it's only aware of
> whatever prototypes have been declared above the call. But that's just a
> warning, not an error. It can still call the function, it just can't
> verify that the number and type of arguments are correct.


Yes. That makes sense, and is more or less what I knew and expected. My last
problem was that I nevertheless sometimes got actual errors, not just
warnings. Having read your explanation, and having thought a bit more about
it, I believe I've found the last piece of the puzzle myself:

The times that I got actual errors were probably the times when used such
badly defined subroutines (prototyped due to my mistaken use of
parentheses) _in the replacement part of a substitution_. I such cases Perl
uses eval, and that means (as far as I can tell) that the compilation does
not happen as the compiler goes through the code from top to end (as you
put it), but afterwards as it gets to evaluate the replacement. If that's a
correct analysis, then everything makes sense to me now.

> You'll get a much more thorough description of the problem, and suggested
> solutions, if you do "use diagnostics" instead of "use warnings".


I'll start doing that. Thanks!

> There are two ways to deal with that. You could declare the sub above the
> rest of the code. Or, you could forward declare the sub, like this:
> [...]
> If you've done any C/C++ programming, you'll feel right at home with this
> declaration/definition split. If you've only done Java before this, you'll
> find it bizarre beyond words.


Actually Perl is my reference point for normality since Perl is the first
programming language I learnt. (Ss some would say my thinking is hoplessly
perverted from the start...) I've done some Java since, but no C(++) - and
a lot of Javascript which obviously has had some bad effects on my Perl-fu.

The problem is that I lernt Perl to a large extent by trial and error way
back then. It's only now, many years later, that I try to delve a little
deaper into things.

Thanks again for all the help!

John Bokma:

> perldoc -f sub might be a great help instead of guessing, experimenting,
> etc. The worst method of learning to program is trial and error: not
> reading documentation and using "experience" from other languages,
> especially if the latter is obtained in exactly the same way (which is
> often the case, somehow).


I did read lots of documentation, but I still wasn't able to find the
answer, which turned out to involve quite a few subtle things - as well as
some old misunderstandings and bad habits of mine.

Actually I think it's impossible to solve things like this without some
guessing and experimenting in addition to reading the documentation. The
Perl documentation is sometimes not the easiest reading.

--
Bertilo Wennergren <http://bertilow.com>
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      10-05-2005
Bertilo Wennergren <(E-Mail Removed)> wrote:
> Sherm Pendley:
>
>> Bertilo Wennergren <(E-Mail Removed)> writes:

>
>>> sub subroutine() {
>>> [...]

>
>>> This works (prints "brrbrrinn\n"), but sometimes when I do stuff like
>>> that (not using any prototyping!)

>
>> The above *is* using a prototype - it's specified as taking no arguments.

>
> Yes, I just found out what my use of parentheses actually means. I use them
> only as a bad habit picked up from Javascript.



Cargo cult programming is just plain silly!


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
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
returning none when it should be returning a list? randomtalk@gmail.com Python 11 05-02-2006 10:26 AM
cannot access Internet after returning from standby =?Utf-8?B?REJI?= Wireless Networking 0 10-31-2005 09:21 PM
Returning multiple variables Kwaj VHDL 2 06-07-2004 10:20 AM
WebService – Returning an Object Karuppasamy ASP .Net 0 01-15-2004 04:38 PM
Re: Net::SNMP - returning huge hex for opaque value dna Perl 0 10-20-2003 02:41 PM



Advertisments