Variable scope in wanted function

PERL

    Next

  • 1. How to get teh line before a last from file
    On Nov 6, 5:28 am, XXXX@XXXXX.COM (Sivasakthi) wrote: > How to get the line before a last line from file?? Here's a few off the top of my head. I'm sure there's more. #1 open my $fh, '<', $file or die $!; my $before_last = (<$fh>)[-2]; #2 open my $fh, '<', $file or die $!; my ($last, $before_last); while (<$fh>) { $before_last = $last; $last = $_; } #3 use File::ReadBackwards; my $bw = File::ReadBackwards->new($file) or die $! $bw->readline(); my $before_last = $bw->readline(); Paul Lalli
  • 2. How to get teh line before a last from file
    Hi All, How to get the line before a last line from file?? Thanks, Siva
  • 3. Get the byte position of previous line from last line in file
    Hi All, I have the text file as following, this first line this is the second line this the third line this is the fourth line this is the sixth line this is the seventh line while opening and reading that text file, is it possible to get the byte position of "this is the sixth line" ?? Thanks, Siva
  • 4. regexp with capture of multiple lines matching a line pattern
    Hi, using perl 5.8.8. i was trying to match for capturing data from a server's response message. Now i have the problem, that within the response there is a head-line with #x next lines, that match a certain pattern. And i want to extract as many data as come: E.g folloing input [...] APNID PDPADD EQOSID VPAA PDPCH PDPTY PDPID 1 2 NO IPV4 1 2 2 NO IPV4 2 3 2 NO IPV4 3 [...] I would like to extract with this: [...] APNID PDPADD EQOSID VPAA PDPCH PDPTY PDPID (?:[ ]+(\\d+)[ ]+(\\d+)[ ]+NO[ ]+IPV4[ ]+(\\d+)\\n)* [...] But it only saves the values of the last line, that matched. The data of previous lines is not captured. How can i manage, that all lines data are captured? I tried a work-around with Regexp::NamedCaptures this way: [...] APNID PDPADD EQOSID VPAA PDPCH PDPTY PDPID (?:[ ]+(?< \@APNIDs >\\d+)[ ]+(\\d+)[ ]+NO[ ]+IPV4[ ]+(\\d+)\\n)* [...] ..."hoping" that using a @APNIDs here would push back the values. But it didn't work. Now i am desperately trying to find out, if there is possible to use a proxy "push_backer" var to @array for assignment, because i guess i can not just use some @array to save multiple hits? But actually i would like an easier way to do this. rgds! Frank

Variable scope in wanted function

Postby rongoral » Tue, 12 Oct 2004 07:17:20 GMT

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



Re: Variable scope in wanted function

Postby noreply » Tue, 12 Oct 2004 08:31:45 GMT



Yes. But you are apparently running the code without warnings enabled,
or else Perl would have indicated the reason for this problem.


One possible solution is to move the ProcessFile() function out from
FindPath(), so the former is no longer a nested sub:

     sub ProcessFile {
         my ($a_files, $file_name) = @_;
         push @$a_files, $File::Find::name if $_ eq $file_name;
     }

and call ProcessFile() from FindPath() with arguments:

     find( \&ProcessFile( \@a_files, $file_name ), $file_path );

And last but not least:

     use warnings;

;-)

-- 
Gunnar Hjalmarsson
Email:  http://www.**--****.com/ 

Re: Variable scope in wanted function

Postby Jenda » Wed, 13 Oct 2004 00:39:05 GMT

rom: Gunnar Hjalmarsson < XXXX@XXXXX.COM >

You can't do that. You'd have to write it like this:

find( sub {ProcessFile( \@a_files, $file_name )}, $file_path );

Another option would be to use an unnamed subroutine like this:

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(sub {
if ($_ eq $file_name){push (@a_files, $File::Find::name);}
}, $file_path);

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


Or (which might very well be fastest) you'd declare the $file_name
and @a_files outside the FindPath and ProcessFile:

{
my ($file_name, @a_files);

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

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

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

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

HTH, Jenda
===== XXXX@XXXXX.COM === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery


RE: Variable scope in wanted function

Postby rongoral » Wed, 13 Oct 2004 00:44:59 GMT



Actually, I am using warnings. However, in the 'real' code, I have placed
the the call to 'find' within an eval block so that I can manage the errors.
Is this why I did not receive any warnings? The difficulties with moving
ProcessFile out of FindPath is that any return values ProcessFile might have
are ignored and it can take no arguments (this is from
http://search.cpan.org/~nwclark/perl-5.8.5/lib/File/Find.pm#The_wanted_funct
ion).

I've setting up a "global" variable like $hr_self->{a_files}, where $hr_self
is an object ref to the module. This requires calling ProcessFile like so:

find(\$hr_self->ProcessFile, $file_path);
or
find(\&ProcessFile($hr_self), $file_path);

File::Find dies here with the complaint "invalid top directory at
/usr/lib/perl5/5.6.1/File/Find.pm line 295, line 36." I'm fairly certain
this is because of the '$hr_self->'. I'm also completely out of ideas for
this. At least when ProcessFile is defined within FindPath, the only
variable trouble I had was with @a_files.

There is a light, however. If ProcessFile is actually an anonymous sub and
called this way:

my $processfile = sub {if ($_ eq $file_name){push (@a_files,
$File::Find::name);}};

find(\&$processfile, $file_path);

There are no errors and @a_files is populated (and depopulated) as it should
be.

Thanks for taking the time to check this out and to write an answer.



Re: Variable scope in wanted function

Postby noreply » Wed, 13 Oct 2004 04:07:21 GMT





I get the same warnings also with such an eval block.


No return values does not matter, since my suggestion didn't make use
of return values from ProcessFile, but the rest does. Jenda showed us
a way to modify that approach to working code.

Sorry for posting non-tested code. :(

<snip>


Yes, that seems to be a nice solution. You can even pass it to find()
by just saying:

     find( $ProcessFile, $file_path );

If you haven't already, to get an understanding of what the original
problem actually was about, you can read the "Variable '%s' will not
stay shared" section in "perldoc perldiag".

-- 
Gunnar Hjalmarsson
Email:  http://www.**--****.com/ 

RE: Variable scope in wanted function

Postby rongoral » Wed, 13 Oct 2004 23:16:56 GMT



Thanks to everyone who replied to this problem.

I discovered that what I had done, inadvertantly, was created a closure with
the ProcessFile function. The closure will act on 'my' vars that are
created outside of its own scope, however, it will retain the values it
assigned to the var. There is a much better explanation in Perl FAQ 7
(http://www.perldoc.com/perl5.8.4/pod/perlfaq7.html#What's-a-closure-).

This is how I ended up solving the issue:

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

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

#- Search file_path Looking For This File
find(\&$process_file, $file_path);

return @a_files;
} # end FindPath

Now, the var $process_file is a coderef. While having stumbled on this
closure business was pretty baffling, I'm glad I did. It's an interesting
concept that I might could use advantageously in the future.

Thanks again -
Ron Goral



Similar Threads:

1.pl/perl function life and variable scope - concurrency

2.pl/perl function life and variable scope -

On Wed, 2003-11-12 at 15:44, Joshua D. Drake wrote:
> Or in other words... code to "strict"

 :-)

 Yes, I do normally. I was simply running a test and came across this
and it caught me by surprise. For the record, my pl/perl function is
this:

CREATE OR REPLACE FUNCTION htdig(text, text)
RETURNS text[] AS '

 my $SearchTerms = $_[0];
 my $HtDigDB = $_[1];
 my @Result = {};
 my $Line = '''';

 #open HTDIG, "/usr/local/htdig/bin/htsearch  ''config=" . $HtDigDB . ";words=" . $SearchTerms .  "'';matchesperpage=1000;";
 open HTDIG, "/bin/cat /home/postgres/" . $SearchTerms . " |";

 while(<HTDIG>) {

    $Line = $_;
    $Line =~ s/^h[^0-9]*//;
    chomp($Line);
    push @Result, $Line;
 }

 close HTDIG;

 return qq/{/ . (join qq/,/, @Result) . qq/}/;
' LANGUAGE plperlu;


I started writing this in C and realized that this was going to be a
couple hundred lines of code - compared to the 23 lines in Perl,
including test lines. All this function needs to do is to take a pipe
from the htsearch and grab integers in the URL that it returns. Then
I'll write a pl/pgSQL wrapper that returns this array as a set.

Pretty sweet, and I couldn't have done it without the help of this list.

Thanks!

Cheers,

Chris

-- 
Christopher Murtagh
Enterprise Systems Administrator
ISR / Web Communications Group 
McGill University
Montreal, Quebec
Canada

Tel.: (514) 398-3122
Fax:  (514) 398-2017

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
      subscribe-nomail command to  XXXX@XXXXX.COM  so that your
      message can get through to the mailing list cleanly

3.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.

4.Vim - limitting search scope to current perl function

Hi there - I've been searching all over to answer this question and
haven't found anything that works.

Basically all I want to do is be able to automatically limit my search
in vim to the current perl function/subruitine.

For i.e.:
------
$this
sub test{
$this = "that";
print "$this";
<curser here>
}
-------

so searching for "this" from where the curser is would find the 2 lines
within the "sub test" function, but would not find the line above it.

Does anyone know if this is possible or if there is a plugin that can
do this?  I've found Tlist and ShowBlockName which help navigate
functions, but in big files this search capability would really be
helpful!

thanks,

//Tanner

5.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

6. trouble with list context assignment for substitution inside File::Find &wanted function

7. comparing and contrasing two approaches to variable scope

8. problem with variable scope



Return to PERL

 

Who is online

Users browsing this forum: No registered users and 42 guest