perl byte code generation with too many file.pl - linux

How to make perl bytecode if sub is there in another file.pl so that I can get all perl script in to binary to give for usage but I am getting codedump warning.
Here is the example how I have done!
File: add.pl
require "util.pl";
$a = 1;
$b = 2;
$res = add($a,$b);
print $res;
File: util.pl
sub add()
{
my ($a,$b) = #_;
my $c = $a + $b;
return $c;
}
1; #to return true
Then when I run:
perlcc add.pl
./a.out
I get
Segmentation fault (core dumped)
I also tried
perlcc add.pl util.pl
but it says
/usr/bin/perlcc: using add.pl as input file, ignoring util.pl
Note:
If both are in single file
perlcc file.pl
and
./a.out
will work

I cannot answer for the actual compiler problem, but let me make a few notes.
<Edit> the more I look at this, the more I think that the problem is the namespacing of the add function. When they are in the same file, the function is declared in the main namespace. I think that would be true of the require-d file too, since there was not package declaration. Either way, these are still some good notes that I hope help. </Edit>
You really should use strict and warnings pragmas
You shouldn't use $a and $b, because they are semi-magical in Perl and should be avoided (yeah, thats a weird one)
Perl prototypes are not the same as most languages, and even then the empty prototype () on your add function is incorrect, best to leave it off
Those things said here is how I would format my files.
File: add.pl
use strict;
use warnings;
use MyUtils;
my $x = 1;
my $y = 2;
my $res = add($a,$b);
print $res;
File: MyUtils.pm
package MyUtils;
use strict;
use warnings
use parent 'Exporter';
our #EXPORT = ('add');
sub add
{
my ($x,$y) = #_;
my $c = $x + $y;
return $c;
}
1;
This uses the more modern module/package formalism for reusable libraries. The use directive contains a require directive, but does it at compile-time rather than run-time.
The Exporter module (and the #EXPORT variable) correctly import the function into the script's namespace (typically main).
Perhaps perlcc will like these changes better; but even if not, these are good practices to get used to.

perlcc was removed from Perl in version 5.10.0 (almost five years ago). The perldelta manual page has this to say:
perlcc, the byteloader and the supporting modules (B::C, B::CC,
B::Bytecode, etc.) are no longer distributed with the perl sources.
Those experimental tools have never worked reliably, and, due to the
lack of volunteers to keep them in line with the perl interpreter
developments, it was decided to remove them instead of shipping a
broken version of those.
Seeing that, I have to suggest that using perlcc with any version of Perl is probably a rather bad idea. It was an experimental feature that never really worked. You probably want to move away from using it.

Related

What is the Lua "replacement" for the pre_exec command in Conky files?

I'm not great at programming, but I was trying to fiddle around with a conky_rc file I liked that I found that seemed pretty straight-forward.
As the title states, I have now learned that the previous command of pre_exec has been long removed and superseded by Lua.
Unfortunately, I cannot seem to find anything directly related to this other than https://github.com/brndnmtthws/conky/issues/62. The thread https://github.com/brndnmtthws/conky/issues/146 references it, and its "solution" states: Basically, there is no replacement and you should use Lua or use a very large interval and execi.
I have found a few more threads that all include the question as to why this function was discontinued, but with no actual answers. So, to reiterate mine, I have absolutely no knowledge of Lua (I've heard of it before, and I've now added a few websites to look at tomorrow since I have spent most of the evening trying to figure out this Conky thing), and I'll probably just give up and do the execi option (my computer can handle it but, I just think it's so horribly inefficient).
Is there an appropriate Lua option? If so, would someone please direct me to either the manual or wiki for it, or explain it? Or is the "proper" Lua solution this?
#Vincent-C It's not working for your script is because the function
ain't getting call. from the quick few tests I did, it seem
lua_startup_hook need the function to be in another file that is
loaded using lua_load, not really sure how the hook function thingy
all works cause I rather just directly use the config as lua since it
is lua.
Basically just call the io.popen stuff and concat it into conky.text
conky.text = [[ a lot of stuff... ${color green} ]];
o = io.popen('fortune -s | cowsay', 'r') conky.text = conky.text ..
o:read('*a')
The comment by asl97 on the first page you cited appears to provide an answer, but a bit of explanation would probably help.
asl97 provides the following general purpose Lua function to use as a substitute for $pre_exec, preceded by a require statement to make io available for use by the function:
require 'io'
function pre_exec(cmd)
local handle = io.popen(cmd)
local output = handle:read("*a")
handle:close()
return output
end
Adding this block of code to your conky configuration file will make the function available for use therein. For testing, I added it above the conky.config = { ... } section.
Calling the Lua pre_exec function will return a string containing the output of the command passed to it. The conky.text section from [[ to ]] is also a string, so it can then be conactenated to the string returned by pre_exec using the .. operator, as shown in the usage section provided by asl97.
In my test, I did the following silly bit, which worked as expected, to display "Hello World!" and the output of the date function with spacing above and below each at the top of my conky display:
conky.text = pre_exec("echo; echo Hello World!; echo; date; echo")..[[
-- lots of boring conky stuff --
]]
More serious commands can, of course, be used with pre_exec, as shown by asl97.
One thing that asl97 didn't explain was how to provide how to concatenate so that the pre_exec output is in the middle of the conky display rather than just the beginning. I tested and found that you can do it like the following:
conky.text = [[
-- some conky stuff --
]]..pre_exec("your_important_command")..[[
-- more conky stuff --
]]

how to pass arguments like 750_000 from command line

I am unable to pass values like 750_000 from command line to a function like usleep via shift. Still getting ".. isn't numeric".
Any ideas?
Thanks.
The 750_000 syntax is valid for numeric literals in source code, where it is simply ignored when populating the value. It is not valid when using a string that's already been created (such as read from commandline arguments) as a number. Numbers can be stored in strings with scientific notation as you noted. Alternatively you could remove the underscores yourself:
use strict;
use warnings;
use Time::HiRes 'usleep';
my $num = shift;
$num =~ tr/_//d;
usleep $num;
Sorry but answering my own question.
It can be done using exponent syntax.
examples:
1_000_000 can be written as 1e6
1_234_567 can be written as
1.234567e6

How do I assure that a module is loaded only if the script is running on Windows?

I have a Perl script that needs to run on both Windows and Linux. The problem is I need to use a Perl module that only applies to Windows.
I have tried the below, but it still includes thie WindowsStuff package.
use strict;
if ($^O eq 'MSWin32' ){
use My::WindowsStuff;
}
use File::Basename;
use Getopt::Long;
...
...
Because use takes effect at compile time, it doesn't respect the ordinary flow control of the code being compiled.
In particular, putting a use inside the false branch of a conditional doesn't prevent it from being processed.
What you can do?
a) require import (run-time):
if( $^O eq 'MSWin32' ) {
require My::WindowsStuff;
My::WindowsStuff->import if My::WindowsStuff->can("import");
}
b) use if (compile-time):
use if $^O eq 'MSWin32', "My::WindowsStuff";

How do I conditionally use threads in a perl script?

I have a perl script that I've developed that runs on hosts that have different versions of perl, sometimes compiled with threads and sometimes without.
I have a
use if $Config{"useithreads"}, "threads";
And all of my thread-specific code is in similar conditionals.
However, during the compile phase, perl still chokes on threads::all, threads::running, etc.
How can I unsure my script runs on both threaded and non-threaded perls?
[ worr on worr-mn1 ] ( manage_usr_local_admin ) % perl -c acct_mgr_ng.pl
Bareword "threads::joinable" not allowed while "strict subs" in use at acct_mgr_ng.pl line 117.
BEGIN not safe after errors--compilation aborted at acct_mgr_ng.pl line 541.
When threads is loaded, perl knows that threads::all (and friends) is a subroutine call, even without parentheses or &; since threads may not be loaded, just explicitly call it with parentheses: threads::all()
use statements are parsed at compile-time. You want to use require or Module::Load to pull in modules conditionally at run-time.
Something like this should work:
use Module::Load ();
if($Config{'useithreads'}) {
Module::Load::load("threads");
}

Manipulate or split string

I've a quick question, that would solve me some problems if possible:
Is it possible to split / manipulate the request-url with nginx?
What I mean is: an url like this: sub.somewhere.com/something/somethingelse
Is turned into:
subsomethingsomethingelse
And then further into:
sub/som/eth/ing/som/eth/ing/els/e
And then the given path is used to retrieve a File (so probably, it has to be stored in a variable that can be re-used, or used directly)
Is this possible somehow? Or if not, what exactly would be possible, and where are the limitations?
(edit) Are there native possibilities to do this, whitout including the PERL Module? Or is that the only way? (maybe a smaller module that only does string handling? )
it is possible and relatively easy, all you need to do is match your location on a regexp with the approriate back references
location ~ (sub).(somewhere).(com)/(some)(thing)/(something)(else) {
set $var1 = $1; # =sub in above example
set $var2 = $2; # =somewhere in above example
set $var3 = $3; # =com in above example
set $var4 = $4; # =some in above example
set $var5 = $5; # =thing in above example
set $var6 = $6; # = something in above example
set $var7 = $7; # = elsein above example
rewrite ^ $1/$2 last; # would be sub/somewhere
}
you need to save the backreferences before the rewrite because the rewrite directive resets the references to those in the regexp first argument (so if you use some other directive like try_files that doesn't do that you coul just use the backreferences directly without saving them)
This can be easily done by using Nginx perl module
I don't know another way or native modules to do this.
You can write your own module for nginx to do such thing, but in fact it is not necessary.
Perl module if quite simple and fast for string manipulation. I have successful experience of using perl module for similar task in production.

Resources