How probably not to hand over a variable from one perl script to another

  • Thread starter Markus Hänchen
  • Start date
J

Jürgen Exner

Markus said:
To summarize for other people having the same question:
Question:
'How can I pass (hand over) a variable from one perl script to
another?'

You can generalize the question to:
'How can I pass (hand over) a variable from one program (regardless of
programming language) to another?'
Answer:
'You cannot. You can only pass scalars via the command line (or via a
temp file) by giving them as arguments when using the system command
(system 'script.pl', $scalar). But you can pass a variable to modules,
i.e. make your second script a module.'

Then the answer becomes:
'You cannot. You can use the normal interprocess communication methods like
signals, command line arguments, files, pipes, sockets, shared memory, ...
to pass the data.
If you want to pass or actually 'share' a variable then in general(*) you
should use modules or whatever concept your programming language provides
for programming_in_the_large.'
(*): Just for completeness: Of course there are some IPCs that allow sharing
variables, too, like e.g. shared memory.

jue
 
D

David Squire

A. Sinan Unur said:
ITYM, 'alas'.

Not necessarily. 'helas' is perfectly good French, and is also used in
(mostly literary) English. The OED does mark it as obsolete though.


DS
 
M

Markus Hänchen

Did you mean @ARGV instead?

Yes, I did, sorry for the typo.

Well, kinda sort of. For once the first argument is more like
'./runit.pl' rather than 'runit8.pl'. Yes, those nitpicking details are
important. Computers are notoriuously unforegiving when you make a typo.

I am running scripts on both Unix (./runit.pl) and Windows (runit.pl),
I know the difference. It is just that when I am quoting other people I
tend to use their syntax, and this gets messy when I quote several
people.
Command line arguments are nice to pass small sets of information. They
are unsuitable for large sets and most OS even impose a limit to the
maximum lenght of the command line. If you still want to pass the
content of a whole array or hash it's easy enough to do:

In the calling program:
system 'myotherprogram', @myarray;
In the called program:
@mynewarray = @ARGV;

But as mentioned before that can easily exceed the limits of your OS.

My arrays are really small, maybe 15 entries, so I am going to try
this. Thanks.

A better method is to use one of the standard methods for data passing:
files, pipes, sockets, shared memory, ....

I guess modules, as suggested by other people, fall also into this category?

Why would you need to take the array apart and put it back together?

My temp file contained both an array and scalars, so instead of trying
to figure it out, I just took the array apart. Using your syntax via
the command line should naturally make that obsolete.

However, for hashes I still have a problem, I guess this is not the
correct syntax:

In the calling program:
system 'myotherprogram', %myhash;
In the called program:
%mynewhash = %ARGV; (or @ARGV)
 
T

Ted Zlatanov

I am realising this. In other words, instead of writing the values of
the variables to a temp file (my original approach), I am writing them
to the command line and reading them back from there, probably a
better approach but stil a pain for arrays and hashes (which I have to
take apart and reassemble for both approaches).

If you need multi-level data structures, write them to a file using
YAML, XML, or something like that. Please don't try to make your own
data language, as appealing as that is to most programmers.

You can easily pass lists and 1-level hashes (just key/value, not
complex values that are lists or hashes in themselves) with the
AppConfig/Getopt modules from the command line, but if you expect your
program to ever need complex data, just bite the bullet now.

Finally, do NOT write your file as executable code so you can then run
eval() on it. Bad idea, even for advanced programmers.

Ted
 
J

Jürgen Exner

A. Sinan Unur said:
I learn something new everyday.

Although, Wikipedia does not know it, my standard dictionaries don't know
it, and only the 2000+ page 8 pound Webster Encyclopedic Dictionary has a
very short entry. Not commonly used, I would conclude.

jue
 
M

Markus Hänchen

without any arguments should give me that element, Perl should be smart
Oh, but, $#arrayname does not give the length of the array. It gives
the last index of the array.

In Matlab length(matrixname) gives you the number of rows. Therefrom
stems my usage of the word length to indicate the number of entries and
since the last index +1 is equal to the number of entries...

<rant>
I consider this poster a good example of what happens when people are
not immediately hit by a clue-by-four. I mean, look at this thread: A
bunch of us patiently explaining the most elementary concepts that one
ought to learn by reading a book, and what do we get in return? "Perl
should be smart enough"? And a complete resistance to learning.

Perl, just like any other programming language, has rules. Those rules
make the language. The programmer learns those rules, and abides by
them. If said programmer does not like the rules of a language, the
programmer should look for another languages which is more to his
liking.

I am out of this thread.
</rant>

I started this thread by trying to amuse you by showing in what a
complicated manner a complete beginner might solve a problem (and
hoping that maybe somebody would be tempted into telling me how much
easier I could have solved it).
 
I

Ian Wilson

Markus said:
Hi,

I guess there are better ways to hand over a variable from one perl
script to another. Knowing very little about Perl I came up with this
solution:

<snip example of using system to invoke one perl script from another>


I can't help thinking that you *may* be missing some very rudimentary
concepts: Subroutines, Libararies and Modules.

1) Subroutines.

You must know about subroutines, is there some reason why your runit.pl
is not made into a subroutine inside your calling perl script (I mean
merge the two perl scripts into a single file)

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

my @test = (12,4,5,10);
print "The sum of @test is ", sum(\@test), "\n";

sub sum {
my $arrayref = shift;
my $total = 0;
foreach my $element (@$arrayref) {
$total += $element;
}
return $total;
}


2) Subroutine libraries

If the runit.pl code needs to be invoked from more than one perl script,
then I'd first make it work as an inline subroutine (as 1. above) then
learn how to separate it into a subroutine library

perldoc -f require

----- 8< ------- myapp.pl
#!/usr/bin/perl
use strict;
use warnings;

require('mylib.pl');

my @test = (12,4,5,10);
print "The sum of @test is ", sum(\@test), "\n";

----- 8< ------- mylib.pl
use strict;
use warnings;

sub sum {
my $arrayref = shift;
my $total = 0;
foreach my $element (@$arrayref) {
$total += $element;
}
return $total;
}
1; # <--- don't forget this.


3) Modules

AFAIK use of require for subroutine libraries has been, to a large
extent, superceded by modules. These take a bit more work to create but
have many advantages.

perldoc -q "create a module"


Hope that helps.
 
D

David Squire

Markus Hänchen wrote:

[snip]
since the last index +1 is equal to the number of entries...

As has now been pointed out several times in this thread, this is not
necessarily the case in Perl.


DS
 
M

Markus Hänchen

Although, Wikipedia does not know it, my standard dictionaries don't
know it, and only the 2000+ page 8 pound Webster Encyclopedic
Dictionary has a very short entry. Not commonly used, I would conclude.

jue

I guess then that is me reading too much French and mixing up languages...
 
J

Jürgen Exner

Markus said:
In Matlab length(matrixname) gives you the number of rows. Therefrom
stems my usage of the word length to indicate the number of entries
and since the last index +1 is equal to the number of entries...

Most of the time, but not necessarily. See "perldoc perlvar" for $[

jue
 
M

Markus Hänchen

2) Subroutine libraries
If the runit.pl code needs to be invoked from more than one perl script,

That is the case for me (I am already using subroutines and know how
useful they are).
then I'd first make it work as an inline subroutine (as 1. above) then
learn how to separate it into a subroutine library

perldoc -f require

----- 8< ------- myapp.pl
#!/usr/bin/perl
use strict;
use warnings;

require('mylib.pl');

my @test = (12,4,5,10);
print "The sum of @test is ", sum(\@test), "\n";

----- 8< ------- mylib.pl
use strict;
use warnings;

sub sum {
my $arrayref = shift;
my $total = 0;
foreach my $element (@$arrayref) {
$total += $element;
}
return $total;
}
1; # <--- don't forget this.


3) Modules

AFAIK use of require for subroutine libraries has been, to a large
extent, superceded by modules. These take a bit more work to create but
have many advantages.

perldoc -q "create a module"

I am going to read about subroutine libraries and modules. Thanks for
the reply.
 
T

tinnews

David Squire said:
Markus H?nchen wrote:

[snip]
since the last index +1 is equal to the number of entries...

As has now been pointed out several times in this thread, this is not
necessarily the case in Perl.
As a sometime (but not frequent) user of perl I sympathise to an
extent with the OP.

The problem (from where I'm looking) with perl is how many, many ways
there are of doing things that hide what is going on, e.g. the
implicit use of $_.

Being used to more picky languages (like C and Java) I never feel safe
with all these things happening 'by themselves'.
 
D

David Squire

David Squire said:
Markus H?nchen wrote:

[snip]
since the last index +1 is equal to the number of entries...
As has now been pointed out several times in this thread, this is not
necessarily the case in Perl.
As a sometime (but not frequent) user of perl I sympathise to an
extent with the OP.

The problem (from where I'm looking) with perl is how many, many ways
there are of doing things that hide what is going on, e.g. the
implicit use of $_.

Being used to more picky languages (like C and Java) I never feel safe
with all these things happening 'by themselves'.

Well, I guess it's to do with familiarity. I suspect the first users of
vehicles with internal combustion engines might have thought: My god!
There is a really complicated lump of metal right next to me, with
explosions going off in it all the time. Explosions! And I'm sitting
next to it!". With familiarity, it is taken for granted, or even not
thought of at all.

If you were a frequent user of Perl I would guess that you would soon
feel safe with the implicit use of $_ etc.... though messing around with
the start index of arrays *is* evil.


DS
 
T

Ted Zlatanov

The problem (from where I'm looking) with perl is how many, many ways
there are of doing things that hide what is going on, e.g. the
implicit use of $_.

Being used to more picky languages (like C and Java) I never feel safe
with all these things happening 'by themselves'.

You must dislike natural languages then. "it" is a perfect example:

Bring me the paper. It is $1. Don't forget to pay for it.

versus:

Bring me the paper. The paper is $1. Don't forget to pay for the
paper.

$_ and such implicit contexts work the way "it" does in English.

I consider Perl a good "caveman" language because it doesn't require
you to name things, only to use them :) Naming things is tedious and
often unnecessary.

Another example:

Do this 10 times. (foreach (1..10) { do something })
[$_ will hold the number]

versus:

Start with i at 1. While i is not 10 or more, increment i by 1. (We
know how this looks in C.)
[i will hold the number]

Ted
 
A

axel

Ted Zlatanov said:
On 3 Aug 2006, (e-mail address removed) wrote:
If you need multi-level data structures, write them to a file using
YAML, XML, or something like that. Please don't try to make your own
data language, as appealing as that is to most programmers.
You can easily pass lists and 1-level hashes (just key/value, not
complex values that are lists or hashes in themselves) with the
AppConfig/Getopt modules from the command line, but if you expect your
program to ever need complex data, just bite the bullet now.
Finally, do NOT write your file as executable code so you can then run
eval() on it. Bad idea, even for advanced programmers.

I am curious as to why this is a bad idea. I would have thought that
using Data::Dumper to save data and then eval'ing it would be the idea
solution for passing such things as arrays and hashes.

Axel
 
U

Uri Guttman

MH> Thanks for the tutorials. About the 'throwing it at the wall', I
MH> did read the first half of a good book on Perl (and browse and
MH> search it as well as the internet before posting here) but there
MH> this saying about learning by doing and learning by making
MH> mistakes.

it probably wasn't a good perl book if you learned all those poor perl
coding ideas. what book was it? there are tons of bad perl books and web
tutorials out there.

MH> I know how to get an item out of an array but if the array contains
MH> only one element calling the array without any arguments should give
MH> me that element, Perl should be smart enough to do this (and I guess
MH> it would be, were it not for the fact that @arrayname is reserved to
MH> give me the number of elements of an array, which I did not know since
MH> I always used $#arrayname to get the length of an array).

you have some major flaws in your perl understanding there. you don't
understand list vs scalar context and you don't 'call' an array. @array
is NOT reserved for anything. it is the array itself. but when it is
evaluated in a scalar context (see context is important in perl, very
important), it is the number of elements in the array.

as paul said, read some good tutes and books. learn.perl.org is a good
site to start with.

uri
 
U

Uri Guttman

ASU> <rant> I consider this poster a good example of what happens when
ASU> people are not immediately hit by a clue-by-four. I mean, look at
ASU> this thread: A bunch of us patiently explaining the most
ASU> elementary concepts that one ought to learn by reading a book,
ASU> and what do we get in return? "Perl should be smart enough"? And
ASU> a complete resistance to learning.

ASU> Perl, just like any other programming language, has rules. Those
ASU> rules make the language. The programmer learns those rules, and
ASU> abides by them. If said programmer does not like the rules of a
ASU> language, the programmer should look for another languages which
ASU> is more to his liking.

and a recent thread was all about how we are an arrogant bunch of
assholes. so how do you handle a case like this? i see a long thread
with many patient answers and an OP who seems to not grasp what he is
being told and obviously has some very broken concepts of perl (possibly
from that unnamed 'good perl book' he partly read. so do we keep telling
him what to do? write his code for him and he won't learn it? encourage
him to read more first? almost any result of this will make us look bad
as we gang up telling him what to do. so to those who flamed me recently
(and plonked, ain't had that in a while), where are you in thepppppppse types
of threads? typically, the nice guys not only finish last, they don't
even show up at the starting line. it does take a thick skin and lots of
perserverence to help here for free. so to those who know our style, go
do it yourself. join the perl beginner's list, post here more
often. answer all those FAQ (and correctly!) over and over. i don't feel
any shame in my perl teaching style. many have paid me for this and
enjoy it my work, strong opinions and all. i offer it here for free so
you can ignore me at your peril or choice. note that i was one of the
technical editors of PBP and if you respect damian, maybe some of that
should reflect onto my work here. you might even want to read what he
said about me in his acknowledgements. i have professional opinions that
have been developed over 32 years of coding on more different kinds of
projects and systems than most of you have ever heard of. i don't come
here for glory or your adulation. i come here to give out my experience
where i feel it can be used or learned from. take it is as i give it or
plonk me as i don't care as long as long as i can help some perl hackers
get better. people who know me well know that i am who i am and you are
not going to change me. better to change yourself.

as for helping the perl community, this is only one small place where i
do this. check my web site for all the many things i help with in many
places. i don't need nor care about random flames about my work in this
group. when you volunteer for the perl foundation, raise funds, give
talks, write articles, modules, work at yapc, etc. then you may have
some platform to comment on what i do here. arrogance is part and parcel
of being good and being able to back it. i promote my modules because i
know how good they are and how well they solve their specific problem
domains. i don't make a dime from them so why is that a problem for
some?

now i feel better (in more ways than one!)

and now back to our usual kindergarten dynamic of a perl newsgroup. i
just feel like a 6th grader here.

uri

PS. hopefully the twit who plonked me recently will read this, but i
doubt it.
 
M

Markus Hänchen

it probably wasn't a good perl book if you learned all those poor perl
coding ideas. what book was it? there are tons of bad perl books and web
tutorials out there.

I've mentioned it several times in this thread, my book is "Learning
Perl" by Phoenix and Schwartz. One of the better solutions to my
problem (splitting code into more than one file), as it has been
recommended here a number of times, is the use of modules. In this book
modules are only mentioned as something prefabricated that one can use.
How to create them and in what situations to create them is not
mentioned in the book.
(I don't want to say modules are not important, I just want to say that
you can have read a decent book about Perl and don't know about the
importance of modules. And I know about it know, thanks to a lot of
helpful people in this thread.)

you have some major flaws in your perl understanding there. you don't
understand list vs scalar context and you don't 'call' an array.

That is exactly the kind of language that I appreciate in these kinds
of newsgroops and what keeps me coming back here...

'Calling an array' was figuratively speaking for using the name of an
array in some manner in one's code to access some kind of information
out of it or from it.

@array
is NOT reserved for anything. it is the array itself. but when it is
evaluated in a scalar context (see context is important in perl, very
important), it is the number of elements in the array.

Using the code '$variable = @array' and not '$variable = $array[0]' to
access the first variable of an array was an unneccessary mistake
(unneccessary in the sense that if I had been asked explicitly which of
the versions is the correct one I would have picked the correct one). I
do dozens of such mistakes every day, but in the end I find them all
(or find another way to code it), otherwise my code would not work and
produce correct results.

I was just trying to explain what my logic must have been that led me
to do such a mistake (I already knew a method to get the number of
entries in an array, $#array+1, thereby my ignorance of the fact that
'$variable = @array' gives you the number of elements was rather an
ignorance of the sort, 'I did not the other method to this'. Secondly,
Perl is such a wonderful language, in that almost always does something
whatever you code, not always what you want or expect, admittedly,
compared to other languages where compilation often fails when you try
to mix e.g. scalars and arrays. So, I sometimes guess what the correct
solution is and see what Perl makes out of it (Yes, I know, one might
call this the 'throw at the wall' technique), but I either go back to
my book and look up the correct notation or just run Perl. Both takes
time, debugging code or consulting a book.)
 
T

Ted Zlatanov

I am curious as to why this is a bad idea. I would have thought that
using Data::Dumper to save data and then eval'ing it would be the idea
solution for passing such things as arrays and hashes.

Because it takes a lot of intelligent understanding, planning, and
prevention to make sure you're not vulnerable to a security breach
that way. I'm not just talking about a system("rm -rf /") call
inserted in your data, but more insidious things like keyloggers.

Your data is also locked to Perl. You'll find it very hard to share
data with another language later if you use Data::Dumper.

Data::Dumper may also save data you don't want saved, e.g. a password
in a data structure you didn't know you were dumping.

Pass data with a data language. I suggested YAML or XML - there are
many others.

Ted
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top