CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
why does it matter where subroutine is defined?

 



Andre
Novice

Aug 5, 2011, 7:13 PM

Post #1 of 12 (4388 views)
why does it matter where subroutine is defined? Can't Post

Here is a simple program:


Code
sub PrintA { print "The value of \$A is $A\n" }  

my($A, $B) = (5, 10);

sub PrintB { print "The value of \$B is $B\n" }

&PrintA;
&PrintB;


Here is the output:


Code
The value of $A is  
The value of $B is 10


Shouldn't the output show blank values for both $A and $B? My understanding is that the "my" function essentially hides variables from all other blocks in a program. So why does the subroutine "PrintB" see the value of $B that is defined in main? Why does it matter if the subroutine is defined before or after the variables are declared? Is there any literature that explains why this happens?


(This post was edited by Andre on Aug 6, 2011, 6:31 PM)


fixles
Novice

Aug 6, 2011, 6:52 AM

Post #2 of 12 (4371 views)
Re: [Andre] why does it matter where subroutine is defined? [In reply to] Can't Post

Hi,

Its not where the sub routines are defined its where you've defined $A. PrintA doesnt know about it.

Dont you get the error:

Name "main::A" used only once: possible typo at subr.pl line 6.
Use of uninitialized value $A in concatenation (.) or string at subr.pl line 6.


Andre
Novice

Aug 6, 2011, 8:05 AM

Post #3 of 12 (4368 views)
Re: [fixles] why does it matter where subroutine is defined? [In reply to] Can't Post

Those are not errors, they are just warnings. I only see them if I have warnings enabled.

Back to the main question. How is my original program any different than this code:


Code
sub PrintA { 
my $B = 10;
&PrintB;
}

sub PrintB { print "The value of \$B is $B\n"; }

&PrintA


The output for this program is:


Code
The value of $B is


Why does &PrintB see $B equal to 10 in the original program, but not in this program?


fixles
Novice

Aug 6, 2011, 8:13 AM

Post #4 of 12 (4365 views)
Re: [Andre] why does it matter where subroutine is defined? [In reply to] Can't Post

I already answered it "Its not where the sub routines are defined its where you've defined $A. PrintA doesnt know about it."

Why because that's the way it is. You should always have warning enabled and you wont make mistakes like this.

Take a look at the Lynda.com Perl Essentials training.


Andre
Novice

Aug 6, 2011, 8:35 AM

Post #5 of 12 (4362 views)
Re: [fixles] why does it matter where subroutine is defined? [In reply to] Can't Post

Let's forget about PrintA. Why does PrintB see $B equal to 10 in the original program, but not in the second program? In other words, why does PrintB see a value that is declared in main (original program), but not if it is declared in PrintA (second program)?


(This post was edited by Andre on Aug 6, 2011, 8:36 AM)


fixles
Novice

Aug 6, 2011, 8:48 AM

Post #6 of 12 (4358 views)
Re: [Andre] why does it matter where subroutine is defined? [In reply to] Can't Post

If your not using strict and warnings you haven't learnt the basics of Perl properly. If stick and warnings are showing errors you haven't created the program correctly.

There is no why, your doing it wrong.


Andre
Novice

Aug 6, 2011, 9:15 AM

Post #7 of 12 (4354 views)
Re: [fixles] why does it matter where subroutine is defined? [In reply to] Can't Post

Why can't you answer my question?


fixles
Novice

Aug 6, 2011, 9:20 AM

Post #8 of 12 (4352 views)
Re: [Andre] why does it matter where subroutine is defined? [In reply to] Can't Post

I did and you didn't understand the answer. Stop being lazy and go learn Perl.


fds
Novice

Aug 6, 2011, 11:11 AM

Post #9 of 12 (4344 views)
Re: [fixles] why does it matter where subroutine is defined? [In reply to] Can't Post

As stated the subs do not know the variables are set. These would be done at the beginning of the script. That way they are predefined and ready. Like this:

Code
# These help during development, but once working turn them off. 
#use strict;
#use warnings;
#use CGI::Carp qw(warningsToBrowser fatalsToBrowser);

print "Content-type: text/html\n\n";

# define your variables
my($A, $B) = (5, 10);

# Run the subs
&PrintA;
&PrintB;

# The sub routines - could be anywhere as long as the variables are defined first.
sub PrintA { print "The value of \$A is $A<br>\n" }
sub PrintB { print "The value of \$B is $B\n" }

----------------------------------------------
fdsaadsfdsaf


Andre
Novice

Aug 6, 2011, 6:27 PM

Post #10 of 12 (4325 views)
Re: [Ted] why does it matter where subroutine is defined? [In reply to] Can't Post

According to my book (Perl for Dummies, 4th Edition, page 229), the "my" function essentially hides a variable from all other blocks in a program. So why would "my" variables declared in the main block be visible to the subroutines? On the other hand, "my" variables declared in a subroutine are not visible to subsequent subroutines (as expected).

Here is another code snippet to highlight my confusion:


Code
my $A = 5; 

sub First {
my $B = 10;
&Second;
}

sub Second {
print "The value of \$A is $A\n";
print "The value of \$B is $B\n";
}

&First


The output of this program is:


Code
The value of $A is 5 
The value of $B is


Andre


FishMonger
Veteran / Moderator

Aug 6, 2011, 9:43 PM

Post #11 of 12 (4318 views)
Re: [Andre] why does it matter where subroutine is defined? [In reply to] Can't Post

Variables declared with the 'my' keyword are lexical variables and are accessible in the enclosing block. That includes child blocks declared inside the parent. Lexical vars declared in one block are not accessible in parent blocks. Since 'sub Second' was declared outside of 'sub First', vars declared in 'First' will not be accessible in 'Second',

You should ALWAYS include the warnings and strict pragmas in EVERY Perl script that you write and the diagnostics pragma will give a more detailed message. If you had included them, they would have pointed you to the problem.

With warnings enabled, you'd receive this:

Quote
Name "main::B" used only once: possible typo at D:\perl\andre.pl line 14.
The value of $A is 5
Use of uninitialized value $B in concatenation (.) or string at D:\perl\andre.pl line 14.
The value of $B is


With diagnostics enabled, you'd receive this:

Quote
D:\perl>andre.pl
Name "main::B" used only once: possible typo at D:\perl\andre.pl line 15 (#1)
(W once) Typographical errors often show up as unique variable names.
If you had a good reason for having a unique name, then just mention it
again somehow to suppress the message. The our declaration is
provided for this purpose.

NOTE: This warning detects symbols that have been used only once so $c, @c,
%c, *c, &c, sub c{}, c(), and c (the filehandle or format) are considered
the same; if a program uses $c only once but also uses any of the others it
will not trigger this warning.

The value of $A is 5
Use of uninitialized value $B in concatenation (.) or string at
D:\perl\andre.pl line 15 (#2)
(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
To suppress this warning assign a defined value to your variables.

To help you figure out what was undefined, perl will try to tell you the
name of the variable (if any) that was undefined. In some cases it cannot
do this, so it also tells you what operation you used the undefined value
in. Note, however, that perl optimizes your program and the operation
displayed in the warning may not necessarily appear literally in your
program. For example, "that $foo" is usually optimized into "that "
. $foo, and the warning will refer to the concatenation (.) operator,
even though there is no . in your program.

The value of $B is


With strict added, you'd get this:

Quote
D:\perl>andre.pl
Global symbol "$B" requires explicit package name at D:\perl\andre.pl line 16.
Execution of D:\perl\andre.pl aborted due to compilation errors (#1)
(F) You've said "use strict" or "use strict vars", which indicates
that all variables must either be lexically scoped (using "my" or "state"),
declared beforehand using "our", or explicitly qualified to say
which package the global variable is in (using "::").

Uncaught exception from user code:
Global symbol "$B" requires explicit package name at D:\perl\andre.pl line 16.
Execution of D:\perl\andre.pl aborted due to compilation errors.
at D:\perl\andre.pl line 19


Additionally, you should not use '&' when calling subs, unless you understand, and want/need its side effects.

I have not read the "Perl for Dummies" book, but I have seen some samples and I was not impressed.

"Learning Perl, Sixth Edition" is the best beginners book that I've found. http://oreilly.com/catalog/9780596001735

You should also get a copy of "Perl Best Practices". http://oreilly.com/catalog/9780596001735

There are a number of other books I could recommend, but I don't want to overwhelm you.


(This post was edited by FishMonger on Aug 6, 2011, 9:45 PM)


fds
Novice

Aug 6, 2011, 11:51 PM

Post #12 of 12 (4311 views)
Re: [FishMonger] why does it matter where subroutine is defined? [In reply to] Can't Post

fishmonger's advice is correct.

I first had "Perl for Dummies" and couldn't make much sense out of it. Since then it's just been a step at a time and only recently began using strict when putting a script together.

I'm not a programmer Andre, but more an artist/designer and so it takes me a lot longer to grasp things. However, once I had stuff that I knew was good code and worked fine, then I built a library and reuse the code in various projects. So when I began using strict and got no errors I knew I had done it right. A few things were not and strict found them so the could be corrected.

Most of these guys here are serious programmers and I found that once I learned a little I could go on to something else, "grow" it myself and only come to a forum when really stuck. Which is the best way, 'cuz then it's in your experience.
----------------------------------------------
fdsaadsfdsaf

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives