question about "package" and variable scope...

PERL

    Next

  • 1. Extract text from a file and write to another.
    Hiya, I'm very new to Perl and my brain is dead. I'm trying to create a simple programme that will extract the pertinent lines (only those with a : in them) from a plain flat text file (that represents my inbox) and write only those files to another text file. This is what I've got so far: use strict; use warnings; my $key; my %hash; my $infile = '/home/sesaworu/mail/sesaworuban.net/test/input'; # store the file my $outfile = '>/home/sesaworu/mail/sesaworuban.net/test/output.txt'; open (INFILE, $infile) or die "cannot open $infile: $!"; # opens the file open (OUTFILE, $outfile) or die "cannot open $outfile: $!"; # opens the file while() { chomp; $key='',next if /^\s*$/; if(/([\w\s]+):(.*)/){ $key=$1; push @{$hash{$key}},$2; } else { push @{$hash{$key}},$_ if $key; } } for(sort keys %hash) { print OUTFILE "$_ : ".join("\n",@{$hash{$_}})."\n"; } How does that look? Cheers Sesa
  • 2. bunzip2 when exec()-ed from perl script outputs garbage data.
    Hello, When the following perl script is executed: #!/usr/bin/env perl use strict; use diagnostics; use warnings; # Header bytes for different zip formats my $GZIP_HEADER = "\x1f\x8b\x08\x08"; my $BZIP_HEADER = "BZh9"; # 42 5a 68 39 my $header_bytes; read STDIN, $header_bytes, 4 or die "Trouble reading input: $!"; if ($header_bytes eq $GZIP_HEADER) { exec "gunzip -f"; die "gunzip doesn't exist or can't be accessed: $!"; } elsif ($header_bytes eq $BZIP_HEADER) { exec "bunzip2 -f"; die "bunzip2 doesn't exist or can't be accessed: $!"; } else { die "Not a proper zip file or unsupported zip format." } I get output like this: BZh91AY (blah blah blah.... I can't copy it because it contains NULs) I've used print statements to prove that it executed bzip2 and found the correct magic number.
  • 3. difficult substitution patterns (commafying)
    John W. Kennedy wrote: > The correct form of the line is: > 1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/; Any advantage of using that form as opposed to 1 while s/(\d+)(\d\d\d)/$1,$2/; ? -Joe
  • 4. Please repost post r-armed.r040 armed and dangerous
    help, How do I add multiple emails to this script # if you would like to be notified of uploads, enter your email address # between the SINGLE quotes. leave this blank if you would not like to be notified $notify = ' XXXX@XXXXX.COM ';
  • 5. update file in real time via CGI script
    Hi, I have a process that is writing to a file and it takes about 5 minutes before the writing is done. I would like to view the file as it is being updated via a cgi script. I tried using a pipe as: open F,"tail -f -n 1000 my_file" or die "$!"; while(<F>) { print; } This program works fine when I run it from the command line. However when I run it as a CGI script(with all headers in place), I cannot see any output, and the browser freezes... The "-n 1000" args for tail are just to make sure I get all the lines from the file. Any help is greatly appreciated. Many thanks, --ravi

question about "package" and variable scope...

Postby Raymundo » Tue, 23 Sep 2008 22:54:16 GMT

Hi all,

I wrote a file that contains two packages:

----------------------------
#!/usr/bin/perl
use strict;
use warnings;

# "main" package, implicitly
sub foo {
    print "sub foo in main\n";
}
our $foo = "scalar foo in main";

foo();             # no problem
print "$foo\n";    # no problem

# "Test" package begins here
package Test;

foo();             # This is an error, because this calls
"&Test::foo()" that doesn't exist
----------------------------

The last "foo();" results in an error, as you know, because "&foo"
exists in "main", not in "Test". It should be "main::foo();".


Ok, then... here is my question...

----------------------------
# (omit the same code as above)

# "Test" package begins here
package Test;

print "$foo\n";    # I think this is an error, too.
----------------------------

Execution result:

sub foo in main
scalar foo in main
scalar foo in main  -- $main::foo is printed...


I thought that the last line would result in an error (just like the
above case).
And I thought it would, if "use strict" is ignored in the scope of
"Test", print null string (the value of $Test::foo).
But the last line printed the value of "$main::foo" variable...

I can't understand this.. Any help would be apprecieated.

Re: question about "package" and variable scope...

Postby Joost Diepenmaat » Tue, 23 Sep 2008 23:06:43 GMT

Raymundo < XXXX@XXXXX.COM > writes:


It isn't an error, it's just confusing. There are two things going on:

* Scoping. 

  our() has lexical scope, so as far as scope is concerned, it doesn't
  care about packages at all. It works basically the same as:

  my $foo = "lexical foo"; # lexicals are NOT bound to any package
  package Test;
  print "$foo\n";

* Association between the variable name and the package variable. 

  As I understand it, our() works as if it creates a new lexical
  variable that is aliased to a package variable of the same name in the
  current package. That is: the current package *at the our()
  statement*, NOT the current package at whatever time you use the
  variable.

See also perldoc -f our:

  ''An "our" declaration declares a global variable that will be visible
  across its entire lexical scope, even across package boundaries.  The
  package in which the variable is entered is determined at the point of
  the declaration, not at the point of use.''

-- 
Joost Diepenmaat | blog:  http://www.**--****.com/ | work:  http://www.**--****.com/ 

Re: question about "package" and variable scope...

Postby Sherm Pendley » Tue, 23 Sep 2008 23:24:08 GMT

Raymundo < XXXX@XXXXX.COM > writes:


That's just "our" doing its job as designed. Your code is basically
the same as the example given in "perldoc -f our":

    An "our" declaration declares a global variable that will be
    visible across its entire lexical scope, even across package
    boundaries.  The package in which the variable is entered is
    determined at the point of the declaration, not at the point of
    use.  This means the following behavior holds:
    
       package Foo;
       our $bar;           # declares $Foo::bar for rest of lexical scope
       $bar = 20;
    
       package Bar;
       print $bar;         # prints 20, as it refers to $Foo::bar
    
sherm--

-- 
My blog:  http://www.**--****.com/ 
Cocoa programming in Perl:  http://www.**--****.com/ 

Re: question about "package" and variable scope...

Postby Raymundo » Tue, 23 Sep 2008 23:26:21 GMT

Oh my God... I misunderstood "our" completely...;;;

Thank you very much.

So, both "our" and "my" have lexical scope... Then, if I want to
declare a variable that is visible in "only this package"... is there
any way to do so? (other than using braces that enclose the entire
package)






Re: question about "package" and variable scope...

Postby Joost Diepenmaat » Wed, 24 Sep 2008 00:15:48 GMT

Raymundo < XXXX@XXXXX.COM > writes:


You can use vars (which is also useful in some other situations):

#!/usr/bin/perl
use strict;
use warnings;

use vars qw($foo);

$foo = "scalar foo in main";

package Test;

print "$foo\n";    # error: Global symbol "$foo" requires explicit package name


-- 
Joost Diepenmaat | blog:  http://www.**--****.com/ | work:  http://www.**--****.com/ 

Re: question about "package" and variable scope...

Postby Raymundo » Wed, 24 Sep 2008 13:37:44 GMT




Ooops.. I couldn't even imagine that "our" and "use vars" have
different scope rule...

Thanks again Joost for your helpful post.

Re: question about "package" and variable scope...

Postby Tad J McClellan » Wed, 24 Sep 2008 20:06:02 GMT





Simply read their documentation...

    perldoc -f our

        ... within the lexical scope of the C<our> declaration ...

    perldoc vars

        the "use vars" and "use subs" declarations are not BLOCKcoped.  
        They are thus effective for the entire file in which they appear...


-- 
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: question about "package" and variable scope...

Postby Hans Mulder » Thu, 25 Sep 2008 07:33:42 GMT



Package variables are global in scope: you can access them from anywhere
using the $package::name notation.

 > (other than using braces that enclose the entire package)

Even that won't help:

$foo = "foo from main\n";

{
         package Foo;

         $foo = "foo from Foo\n";
}

print $foo;       # foo from main
print $Foo::foo;  # foo from Foo

You can use the $Foo::foo notation to access variables in packages
that aren't mentioned anywhere else in your script.  Perl will
silently create the package if that's what it takes to make this work.

If you want to restrict visibility, you'll have to use "my".  But "my"
pays attention only to braces and file boundaries, not to packages.

Hope this helps,

-- HansM

Re: question about "package" and variable scope...

Postby Martin ?UTF-8?Q?KiC39Fner » Fri, 26 Sep 2008 03:46:01 GMT

Sherm Pendley wrote :
This does not work("print $bar" will not print anything in this case),
if Bar is in a separate file Bar.pm and included with 'use Bar;

Why?
How can I use variables across Packages wich are in separate files?

Thanks in advance
regards
Martin

-- 
perl -e '$S=[[73,116,114,115,31,96],[108,109,114,102,99,112],
[29,77,98,111,105,29],[100,93,95,103,97,110]];
for(0..3){for$s(0..5){print(chr($S->[$_]->[$s]+$_+1))}}'

Re: question about "package" and variable scope...

Postby Sherm Pendley » Fri, 26 Sep 2008 04:05:14 GMT

Martin Kier < XXXX@XXXXX.COM > writes:


Our declares variables as being global within a lexical context; a
different file is in a different lexical context.


Use the full package name - i.e. "print $Foo::bar;"

Or, have a look at 'perldoc Exporter' if you'd like to make the
"short" form available to code that uses your module.

sherm--

-- 
My blog:  http://www.**--****.com/ 
Cocoa programming in Perl:  http://www.**--****.com/ 

Re: question about "package" and variable scope...

Postby Ben Morrow » Fri, 26 Sep 2008 04:11:16 GMT

Quoth Martin =?UTF-8?Q?Ki=C3=9Fner?= < XXXX@XXXXX.COM >:

No. Seperate files have separate lexical scopes: 'my' variables are
never visible across files, and 'our' variables must be referred to by
their full package name.


The first question is: are you sure you need to? It's often a bad idea
to do this; it may be better to provide a function or OO interface to
the variable.

That said, you have three options:

    1. Refer to the variable by its fully-qualified name, $Foo::bar.

    2. Export the variable into the 'Bar' namespace with Exporter,
    something like this:

        package Foo;

        use base qw/Exporter/;
        our @EXPORT_OK = qw/$bar/;

        1;

        package Bar;

        use Foo qw/$bar/;

        1;

    3. Make a new 'our' variable in the second file that refers to
    $Foo::bar:

        package Bar;

        #...

        package Foo;
        our $bar;
        package Bar;

        #...

        1;

Ben

-- 
The Earth is degenerating these days. {*filter*} and corruption abound.
Children no longer mind their parents, every man wants to write a book,
and it is evident that the end of the world is fast approaching.
       Assyrian stone tablet, c.2800 BC                         XXXX@XXXXX.COM 

Re: question about "package" and variable scope...

Postby John Bokma » Fri, 26 Sep 2008 04:14:22 GMT




 http://www.**--****.com/ 

-- 
John     http://www.**--****.com/ 

Perl help in exchange for a gift:
 http://www.**--****.com/ 

Re: question about "package" and variable scope...

Postby Martin ?UTF-8?Q?KiC39Fner » Fri, 26 Sep 2008 04:52:17 GMT

Sherm Pendley wrote :


Thank you. I wasn't aware of this.


'perldoc Exporter' explains how to use Exporter in modules (I didn't
read it thoroughly yet).
Is it also possible to use it in the main script to make variables
declared in the main script accessible inside the module?

I know I can use '$main::variablename' but I am just interested if I
could could also use Exporter for this.

regards
Martin

-- 
perl -e '$S=[[73,116,114,115,31,96],[108,109,114,102,99,112],
[29,77,98,111,105,29],[100,93,95,103,97,110]];
for(0..3){for$s(0..5){print(chr($S->[$_]->[$s]+$_+1))}}'

Re: question about "package" and variable scope...

Postby Martin ?UTF-8?Q?KiC39Fner » Fri, 26 Sep 2008 04:54:49 GMT

Tad J McClellan wrote :



I wasn't aware that the lexical scope is restricted to the file.
Thanks to sherm I am now.

regards
Martin


-- 
perl -e '$S=[[73,116,114,115,31,96],[108,109,114,102,99,112],
[29,77,98,111,105,29],[100,93,95,103,97,110]];
for(0..3){for$s(0..5){print(chr($S->[$_]->[$s]+$_+1))}}'

Re: question about "package" and variable scope...

Postby Sherm Pendley » Fri, 26 Sep 2008 05:10:53 GMT

Martin Kier < XXXX@XXXXX.COM > writes:


Not that I know of, and for good reason. Modules should be self-
contained, with as little knowledge as possible of anything outside of
their own package. If the main program needs to provide some variable
to the module, it should either set a variable in the module's
package, or pass it to a function (or method) that the module
supplies.

For example, when you're using the CGI.pm module, you use a variable
in the module's name space ($CGI::POST_MAX) to set the maximum amount
of data that will be accepted from a form.

sherm--

-- 
My blog:  http://www.**--****.com/ 
Cocoa programming in Perl:  http://www.**--****.com/ 

Similar Threads:

1.newbie question about scope, variables, declarations of variables and option strict (as in perl)


Hello,

I am trying to understand the syntax error I receive in a code similar to
this.

1 require 'logger'
2
3 log = logger.new  #some other logger settings are ignored.

4 def func
5   log.debug "a statement" # error is reported here when func is called
below
6  # some code
7 end
8
9 #some code continues
10 func


When func is called, an error is reported on line-5 saying that undefine
local variable log etc. I understand that functions create scopes and log is
seen as local variable  which is not defined in that scope. As it is
qualified with no scope operator, interpreter thinks that it is local but
can not find definition of the log before it's usage but also in the
parameter list and I understand that. On the other hand, I can use log
without qualifying it with a scope symbol anywhere in the same file if it is
not in a function. I know that loops, if statements etc are built into the
language and do not create scope. Code blocks inherit the locals. So it is
meaningful that I can use it anywhere else. When I qualify log with $ as
$log, it becomes global and I no longer receive error. I have tried it
qualifying with @ etc. but the received the same error. What I am asking is,
what is scope of log?. What kind of variable is it? It is the local or
instance variable of what, Object? I know that func is private to the
Object. But what about log?  How  can  I  access it in a function without
making it global?

Is there a way to make variables local to a file as perl does with "my".

Is there a strict option that prevents unintended variable creation because
of typos. Is there a way force predeclaration of variables?

Thanks.

2.Question about Modules and Variable Scope

3.Question about variable scope

In the code snippet below, why can't I access the $nntp variable, unless I
instantiate it within the ListGroups() subroutine?

-Thanks



#!/usr/bin/perl -w

#This nntp instance cannot be used in ListGroups()
#sub below:

# $nntp = Net::NNTP->new($newshost);
# $nntp->authinfo($username,$password);
.
.
.

sub ListGroups()
{
  #Need to instantiate $nntp here for this to work:

  $nntp = Net::NNTP->new($newshost);
  $nntp->authinfo($username,$password);  

  my $groups = $nntp->list() or die "Cannot get group list";

  print join("\n", keys %$groups), "\n";

  $nntp->quit();

  return(0);
} 

4.scope of the variable?

Hello All,
I have following question regarding accessing variable from other module:

In test.pm I have following:

#BEGIN OF THE TEST.PM
package test;

use strict;
use warnings;

#
# The object responsible for managing the database connections.
#
my $dbaccess = undef;

-somewhere else 
$dbaccess = new xxxx::xxx::DBAccess( %dbURL);

….
….

#END OF THE TEST.PM

In test2.pm I have following:

#BEGIN OF THE TEST2.PM
package test2;

use strict;
use warnings;

….
#  How to test::dbaccess ??

#END OF THE TEST2.PM


My question is how to access $dbaccess variable (object) defined and initialized in test.pm within test2.pm module?

Thanks,
Bogumil

5.Variable scope in wanted function

Greetings All -

I am having some difficulty with a module that is using File::Find.  The
method is below.

The idea is to enter this method feeding it a file name and beginning
directory and then looking for all occasions of $file_name and push those
addresses into @a_files.  This works fine until I need to use FindPath again
during the same session.  What I'm finding is that while @a_files looses
scope within FindPath itself, it does not in ProcessFile.  In other words,
when I exit FindPath and come back into it later, @a_files is an uninitiated
array.  However when ProcessFile is called, @a_files has retained the values
it had from the last call to FindPath.

Am I making sense?


sub FindPath
    {
    #- Var Declaration And Initialization
    my ($hr_self, $file_name, $file_path) = @_;
    # Array to fill with file paths
    my @a_files = ();

    # Search file_path for the file
    find(\&ProcessFile, $file_path);

    #- The Subroutine To Process Files And Directories
    sub ProcessFile
        {if ($_ eq $file_name){push (@a_files, $File::Find::name);}}

    # Return the paths found
    return @a_files;
    }   # end FindPath

Peace -
Ron Goral


6. comparing and contrasing two approaches to variable scope

7. problem with variable scope

8. Variable scope



Return to PERL

 

Who is online

Users browsing this forum: No registered users and 91 guest