Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
i have assigned a global variable at start of my script which is empty string and i assigned a value to that inside subroutine . When the script enters the subroutine second time that variable is null and assigned new value .
I need to have the variable name constant for some subroutine calls and then change the value in the subroutine when my condition match
first time it call the subroutine this variable will be empty enter the loop and in the loop i will assign the variable.. next time when it enter the sub routine i want to use that variable value until the condition is met .
Here is the sample code
#!/usr/bin/perl
my $Next_5minus = '';
sub write_alog {
if (my $Next_5minus eq '')
{
........
.........
}
elsif ( $start_mtime < $end_mtime )
{
say $fh join("\n", #$alog);
}
elsif ( $start_mtime > $end_mtime )
{
my $Next_5minus = <will assign value>
..........
}
}
If you want people to help you with your problems, it's polite to make it as simple as possible for them to help you. As a minimum, you should do the following:
Provide a short, self-contained, runnable program that demonstrates your problem.
Clean up the indentation in your code to make it easy to follow.
Add use strict and use warnings to your code and clean up the problems they point out.
In this case, I suspect you'll see warnings about variables that mask variables of the same name. You define three copies of your $Next_5minus variable. Each of them will be initialised as undef as it is created and will disappear as it goes out of scope.
Try removing the extraneous my statements from your code and see if that fixes your problem.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
Why my sub cannot get hidden in the scope of function such in
use strict;
sub out{
my sub this{my $n=9;print "\n$n"} my $i=7; my $j=3
}
&this;
9
Please help solve
As described in the documentation in perldoc perlsub, a lexical subroutine is only visible inside the block they are created:
These subroutines are only visible within the block in which they are declared...
You try to call the sub outside the block, therefore Perl cannot see it. This is also the entire point of using lexical scope: You are trying to restrict the range.
If you had use warnings enabled you would get the warning:
Undefined subroutine &main::this called at ...
You have to use the lexical sub inside the block -- in this case another sub -- like this:
sub out {
my sub this {
....
}
this(); # <---- visible here
}
this(); # wrong, not visible here
Also, using & when calling a sub has a special meaning. As described in perlsub:
&NAME; # Makes current #_ visible to called subroutine.
The normal way to call a sub is by adding parens after: this(). The different ways to call a sub are also listed in perldoc perlsub. Note that there is hidden functionality in the different styles.
NAME(LIST); # & is optional with parentheses.
NAME LIST; # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME; # Makes current #_ visible to called subroutine.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am looking at Perl script and I have a line:
my (#parmTypesList) = #$function_type_ref;
$function_type_ref is a string that is passed to the current function.
What does #$ means ?????
#$var is short for #{ $var } and equivalent to $var->#*. It is an array dereference.
It expects $var to hold a reference to an array, and it produces one of the following:
In scalar context, the number of elements of the array
In list context, the value of the elements of the array.
When an array is expected (e.g. #$var = ..., push #$var, ...), the array itself.
In this case, it's the second.
Despite the name, in no way would a reference to a function work.
But a string might work, since a string can be used as a reference. In this situation, the string is expected to be the name of the variable. This is a horrible, horrible thing to do, so we tell Perl not to let us do this by using use strict; or use v5.12;.
Just to be clear: You should ALWAYS use use strict; or equivalent.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
As i have read ,"There’s another problem with this subroutine.This subroutine works properly only if called with exactly two
Excess parameters are ignored—since the subroutine never looks at $_[2] "
but when I passed multiple arguments its working,so I'm not able to conclude the above statement so can anyone help me in sorting out this problem.
sub privacy{
$_[0]+$_[1]+$_[2]+$_[3];
}
$x=&privacy(3,4,5,6);
print $x,"\n";`
Expected:
7
Actual:
18
but this result is contradicting.
I think you're reading Learning Perl. We present a subroutine that finds the maximum of two arguments. It looks something like this:
sub max {
if( $_[0] > $_[1] ) { ... }
else { $_[0] }
}
If you call it with two arguments, it works out:
max( 1, 2 )
max( 5, 6 )
max( 9, 0 )
If you call it with three arguments, that particular subroutine ignores the third argument because that particular subroutine only looks at the first two:
max( 1, 2, 3 ) # ignores 3, so returns 2
You can write some other subroutine that looks at more arguments, but that's a different subroutine.
Unless you tell Perl otherwise (and I'll ignore that here), it will take as many arguments as you care to give it and they all show up in the special variable #_. How you use that is up to you.
You are misunderstanding the meaning of the sentence:
Excess parameters are ignored—since the subroutine never looks at
$_[2]
What is meant by that is that in a perl subroutine (as in any language) if you don't use a parameter then it's not used.
In the particular example that the above sentence refers to, parameter 2, etc., are not used in the code so they are 'ignored'. They're available if you want to use them, they're just not used in that particular example.
However in YOUR code you are using them.
If that's what they said, and if that's the code they were talking about, then they are wrong. The sub clearly "looks at $_[2]".
3+4+5+6 is 18, and that's exactly what the code the outputs.
$ perl -e'
sub privacy{
$_[0]+$_[1]+$_[2]+$_[3];
}
$x=&privacy(3,4,5,6);
print $x,"\n";
'
18
Note that the code has issues (& used on the sub call even though they are no prototypes to override, and $x isn't scoped), so you shouldn't be taking lessons from whomever wrote that code.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I've created a subroutine named "MENU" with a label named "INIT_MENU" at the top of the subroutine, but when i call this label i got a error : Can't goto subroutine outside a subroutine at program.pl line 15
Here is an example:
sub MENU {INIT_MENU: print "blah blah";}
and here is the line 15:
goto &MENU, INIT_MENU;
Sorry if it is a duplicated question, i searched in all possible places and even in the official site of Perl
The goto expects a single argument, so this code first executes goto &MENU and then after the comma operator it evaluates the constant INIT_MENU in a void context (drawing a warning).
The purpose of goto &NAME is to replace the subroutine in which it is encountered with subroutine NAME; it doesn't make sense calling it outside of a subroutine and this is an error. From perldiag
Can't goto subroutine outside a subroutine
(F) The deeply magical "goto subroutine" call can only replace one subroutine call for another. It can't manufacture one out of whole cloth. In general you should be calling it out of only an AUTOLOAD routine anyway. See goto.
A comment on the purpose of this.
A lot has been written on the harmfulness of goto LABEL.† Not to mention that INIT_MENU: cannot be found when hidden inside a routine. The upshot is that there are always better ways.
A sampler
Call the function and pass the parameter
MENU(INIT_MENU);
sub MENU {
my $menu = shift;
if ($menu eq 'INIT_MENU') { ... }
...
}
If, for some reason, you want to 'hide' the call to MENU use goto &MENU as intended
sub top_level { # pass INIT_MENU to this sub
...
goto &MENU; # also passes its #_ as it is at this point
# the control doesn't return here; MENU took place of this sub
}
This altogether replaces top_level() with MENU() and passes on its #_ to it. Then process input in MENU as above (for example) to trigger the chosen block. After this "not even caller will be able to tell that this routine was called first," see goto. Normally unneeded
Why even have MENU()? Instead, have menu options in separate subs and their references can be values in a hash where keys are names of options. So you'd have a dispatch table and after the logic (or user choice) selects a menu item its code is run directly
my %do_menu_item = ( INIT_MENU => sub { code for INIT_MENU }, ... );
...
$do_menu_item{$item_name}->();
Menu systems tend to grow bigger and more complex with development. It would make sense to adopt OO from start, and then there are yet other approaches for this detail
If you find yourself considering goto it may be time to reconsider (some of) the design.
† See for instance this post and this post. It's (even) worse than that in Perl since there are specific constructs (and restrictions) for situations where goto can be argued acceptable, so there is even less room for it. One example is jumping out of nested loops: there are labels in Perl.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I want to do command line argument parsing for a directory path in perl. I want to make this argument as optional.
so when the user gives path, it showed be assigned to a variable $release_model else it will execute other code I have written for finding directory from main directory. I am new to perl but somehow coded following. Can anybody help?
Getopt::Long
my $command_line = $GetOptions(\%Opts, "help|h","email=s#","test","model");
if($command_line==0){
print "$PROGRAM: no arguments are given";
Usage{};
}
else die "No arguments were given"
But it doesn't accept model as optional argument and throws error.
I just started working with perl.
It is quite hard to guess what exactly you are after as the code provided contains lots of errors and other features not described. But to start learning with something simple, here is something that I hope matches your requirements.
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
my $release_model = '/path/to/"main directory"'; # default value
GetOptions( 'model=s' => \$release_model )
or die("Error in command line arguments\n");
print "Release model is: $release_model\n";
If you save this to a file (e.g. my_program.pl) and make it executable then you can see it provides these features:
If you call it without arguments ./my_program.pl, the default value of $release_model will be used.
If you call it with argument model (e.g. ./my_program.pl --model /another/directory), the provided value will be assigned to $release_model.
If you call it with wrong arguments (e.g. ./my_program.pl --mdoel), it prints reasonable error message and exits.
Try it yourself. And go and read some tutorial on Perl if you want to do some serious work.