This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does 1; mean in Perl?
I'm new to Perl and learning how to build a class with Perl.
As from this example:
http://www.tutorialspoint.com/perl/perl_oo_perl.htm, I see a line which is written as "1;"
just can't find information about this interesting line from perldoc.perl.org
Do you know what it is? And why is it there in the Perl source code?
A module is normally a bunch of subroutine definitions, but it can also include code that is not in a subroutine (such as initialisation code). This code might fail, so Perl lets you indicate this by returning false whereupon Perl aborts with an error.
However, since the default return value is false, we must explicitly return true at the end of a module.
The perldocs have this to say:
The file must return true as the last statement to indicate successful execution of any initialization code, so it's customary to end such a file with 1; unless you're sure it'll return true otherwise. But it's better just to put the 1; , in case you add more statements
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 1 year ago.
Improve this question
I wrote in code
my $sql = ...
my $sth = $dbh->prepare($sql);
eval {
$sth->execute;
}
or do {
# die "SQL Error: $DBI::errstr\n";
addToLog("SQL Error: $DBI::errstr\n");
sleep(30);
next mysql_recover;
};
but checker swears I can't use next inside eval. How to rewrite otherwise?
The problem is in a scope enclosing the shown code (which isn't shown). From next
next LABEL
next EXPR
next
The next command is like the continue statement in C; it starts the next iteration of the loop [...]
So the shown code should be in a loop, with the label mysql_recover. Or in a block with such a label, since a block is a loop that executes once (but then next should be last).
However, we can't tell what is wrong without more code or the actual error message. The shown code doesn't give any hints since a next LABEL; is legit only to target structures that are subject to flow control so the mere acceptance of that statement implies that next is fine.
That do block is not a part of the eval so I don't know what your checker might mean.
But, if there were a next inside of eval, then
eval BLOCK does not count as a loop, so the loop control statements next, last, or redo cannot be used to leave or restart the block.
I'd like to also comment on that eval.
The $sth->execute shown as the sole statement in the eval can return an undef, if there is an error -- and so your eval-handler (the do block) would trigger in that case. If that's your intent then fine, but that'd be confusing since an eval is meant to guard against exceptions (a die).
A full idiom is eval { ...; 1 } or do {...};, so the eval always returns success (that 1) unless a die was thrown . So or do runs only if there was an exception, not on "ordinary" errors (like an undef from DBI...).
Another way to handle that would be to explicitly check for errors from $sth->execute, what need be done anyway. (But then add that 1 as well, against an unexpected false. Why not.)
(There is still some fine print about $# but that would take us elsewhere)
So I've been diving into Perl 6 and have been looking at interpreting another language using Perl 6's operator definitions. I understand that this could be done by parsing the code but I'm looking to push Perl 6's capabilities to see what it can do. Having this functionality would also make the parsing a lot easier
I'm trying to make a variable definition in a C-style format.(The language isn't important)
Something like:
char foo;
Where the char represents the type and the foo is the variable name. From my understanding the char can be interpreted using an operator definition like so:
sub prefix:<char>($input) {
say $input;
}
Which calls a subroutine with the foo as $input. The idea from here would be to use foo as a string and hold it's reference in a hash somewhere. The problem with this is that Perl 6 seems to see any bareword as a function call and will complain when it can't find the "Undeclared routine".
I've looked possibly everywhere for an answer to this and the only thing that makes me still think that this may be possible is the qw function from Perl 5 which is now < > in Perl 6. The < > is obviously an operator which leads me to believe that there is a subroutine defined somewhere that tells this operator how to work and how to deal with the bareword input.
So to my question:
Is there a way of accepting bareword input into a subroutine just like the < > operator does?
Cheers!
The best way to do that would be to create a Grammar that parses your language. If you additionally want it to run the DSL you have just created, combine it with Actions.
This question already has answers here:
What does the function declaration "sub function($$)" mean?
(2 answers)
Closed 7 years ago.
I have been browsing a few of the perl modules where they have used $$%, $$, $$$, #, $%, #.. and so on in the function arguments.
I understand that $$ in the argument ensures that you have to pass 2 non-optional parameters and $ for 1 non-optional parameter. Do the others have similar meaning as well?
These are function prototypes. Everything you need to know about prototypes is in perlsub.
Before you read it a second time, read all of the answers in Why are Perl 5's function prototypes bad? and Far More Than Everything You've Ever Wanted to Know about Prototypes in Perl and see if it disabuses you of the notion to use prototypes.
This question already has answers here:
How do I get perl -c to throw Undefined or Undeclared function errors?
(4 answers)
Closed 8 years ago.
perl -wle 'if (0) {no_such_func()}'
The above runs without errors, despite the -w, because no_such_func()
is never called.
How do I make Perl check all functions/modules I reference, even ones
I don't use?
In a more realistic case, some functions may only be called in special
cases, but I'd still like to make sure they exist.
EDIT: I installed perlcritic, but I think I'm still doing something wrong. I created this file:
#!/bin/perl -w
use strict;
if (0) {no_such_func();}
and perlcritic said it was fine ("source OK"). Surely static analysis could catch the non-existence of no_such_func()? The program also runs fine (and produces no output).
You can't do it because Perl doesn't see if functions exist until runtime. It can't. Consider a function that only gets evaled into existence:
eval 'sub foo { return $_[0]+1 }';
That line of code will create a subroutine at runtime.
Or consider that Perl can use symbolic references
my $func = 'func';
$func = "no_such_" . $func;
&$func;
In that case, it's calling your no_such_func function, but you can't tell via static analysis.
BTW, if you want to find functions that are never referenced, at least via static analysis, then you can use a tool like Perl::Critic. See http://perlcritic.com/ or install Perl::Critic from CPAN.
Hmm, this is difficult: When Perl parses a function call, it doesn't always know whether that function will exist. This is the case when a function is called before it's declared:
foo();
sub foo { say 42 }
Sometimes, the function may only be made available during runtime:
my $bar = sub { say 42 };
my $baz = sub { say "" };
*foo = rand > 0.5 ? $bar : $baz;
foo();
(I'd like to mention the “Only perl can parse Perl” meme at this point.)
I'm sure you could hack the perl internals to complain when the function can't be resolved before run time, but this is not really useful considering the use cases above.
You can force compile-time checks if you call all subs without parentheses. So the following will fail:
$ perl -e 'use strict; my $condvar; if ($condvar) {no_such_func}'
Bareword "no_such_func" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
(However, it does not fail if you write if (0), it seems that perl's optimizer is removing the whole block without checking any further)
This has the consequence that you have to define all subroutines before using them. If you work like this, then sometimes "forward" declarations are necessary. But then it's possible that a forward declaration never gets a definition, which is another possible error case.
What I want to achieve:
###############CODE########
old_procedure(arg1, arg2);
#############CODE_END######
I have a huge code which has a old procedure in it. I want that the call to that old_procedure go to a call to a new procedure (new_procedure(arg1, arg2)) with the same arguments.
Now I know, the question seems pretty stupid but the trick is I am not allowed to change the code or the bad_function. So the only thing I can do it create a procedure externally which reads the code flow or something and then whenever it finds the bad_function, it replaces it with the new_function. They have a void type, so don't have to worry about the return values.
I am usng perl. If someone knows how to atleast start in this direction...please comment or answer. It would be nice if the new code can be done in perl or C, but other known languages are good too. C++, java.
EDIT: The code is written in shell script and perl. I cannot edit the code and I don't have location of the old_function, I mean I can find it...but its really tough. So I can use the package thing pointed out but if there is a way around it...so that I could parse the thread with that function and replace function calls. Please don't remove tags as I need suggestions from java, C++ experts also.
EDIT: #mirod
So I tried it out and your answer made a new subroutine and now there is no way of accessing the old one. I had created an variable which checks the value to decide which way to go( old_sub or new_sub)...is there a way to add the variable in the new code...which sends the control back to old_function if it is not set...
like:
use BadPackage; # sub is defined there
BEGIN
{ package BapPackage;
no warnings; # to avoid the "Subroutine bad_sub redefined" message
# check for the variable and send to old_sub if the var is not set
sub bad_sub
{ # good code
}
}
# Thanks #mirod
This is easier to do in Perl than in a lot of other languages, but that doesn't mean it's easy, and I don't know if it's what you want to hear. Here's a proof-of-concept:
Let's take some broken code:
# file name: Some/Package.pm
package Some::Package;
use base 'Exporter';
our #EXPORT = qw(forty_two nineteen);
sub forty_two { 19 }
sub nineteen { 19 }
1;
# file name: main.pl
use Some::Package;
print "forty-two plus nineteen is ", forty_two() + nineteen();
Running the program perl main.pl produces the output:
forty-two plus nineteen is 38
It is given that the files Some/Package.pm and main.pl are broken and immutable. How can we fix their behavior?
One way we can insert arbitrary code to a perl command is with the -M command-line switch. Let's make a repair module:
# file: MyRepairs.pm
CHECK {
no warnings 'redefine';
*forty_two = *Some::Package::forty_two = sub { 42 };
};
1;
Now running the program perl -MMyRepairs main.pl produces:
forty-two plus nineteen is 61
Our repair module uses a CHECK block to execute code in between the compile-time and run-time phase. We want our code to be the last code run at compile-time so it will overwrite some functions that have already been loaded. The -M command-line switch will run our code first, so the CHECK block delays execution of our repairs until all the other compile time code is run. See perlmod for more details.
This solution is fragile. It can't do much about modules loaded at run-time (with require ... or eval "use ..." (these are common) or subroutines defined in other CHECK blocks (these are rare).
If we assume the shell script that runs main.pl is also immutable (i.e., we're not allowed to change perl main.pl to perl -MMyRepairs main.pl), then we move up one level and pass the -MMyRepairs in the PERL5OPT environment variable:
PERL5OPT="-I/path/to/MyRepairs -MMyRepairs" bash the_immutable_script_that_calls_main_pl.sh
These are called automated refactoring tools and are common for other languages. For Perl though you may well be in a really bad way because parsing Perl to find all the references is going to be virtually impossible.
Where is the old procedure defined?
If it is defined in a package, you can switch to the package, after it has been used, and redefine the sub:
use BadPackage; # sub is defined there
BEGIN
{ package BapPackage;
no warnings; # to avoid the "Subroutine bad_sub redefined" message
sub bad_sub
{ # good code
}
}
If the code is in the same package but in a different file (loaded through a require), you can do the same thing without having to switch package.
if all the code is in the same file, then change it.
sed -i 's/old_procedure/new_procedure/g codefile
Is this what you mean?