eval, "adding up" words to create a variable?

T

Tomasz Chmielewski

I have a couple of variables, like:

my $thing_added = "test1";
my $otherthing_added = "test2";


I also have an array:

@array = ("thing", "otherthing", "no_such_variable");


Now, I would like to go through every element in the array, and check if
there is a corresponding "<array_element>_added" variable.


For example, for "thing", I would like to check if there is a
$thing_added variable. This should evaluate true, as I defined that
variable earlier.

Similarly, for "otherthing", I would like to check if there is a
$otherthing_added variable. This one should also evaluate true.

For "no_such_variable" element, a check for $no_such_variable_added
should evaluate false, as this variable was not defined.


I tried using "eval" to construct a variable out of yet another variable
value and a "_added" word, but haven't been successful.

Any hints?
 
J

Josef Moellers

Tomasz said:
I have a couple of variables, like:

my $thing_added = "test1";
my $otherthing_added = "test2";


I also have an array:

@array = ("thing", "otherthing", "no_such_variable");


Now, I would like to go through every element in the array, and check if
there is a corresponding "<array_element>_added" variable.


For example, for "thing", I would like to check if there is a
$thing_added variable. This should evaluate true, as I defined that
variable earlier.

Similarly, for "otherthing", I would like to check if there is a
$otherthing_added variable. This one should also evaluate true.

For "no_such_variable" element, a check for $no_such_variable_added
should evaluate false, as this variable was not defined.


I tried using "eval" to construct a variable out of yet another variable
value and a "_added" word, but haven't been successful.

Any hints?

Every time you want to use variables as part of variable names, you're
better off using a hash.

Usually you save your life by using a hash as you usually get stoned to
death by asking these kinds of questions here.

Usually,

Josef
 
B

Ben Morrow

Quoth Tomasz Chmielewski said:
I have a couple of variables, like:

my $thing_added = "test1";
my $otherthing_added = "test2";


I also have an array:

@array = ("thing", "otherthing", "no_such_variable");


Now, I would like to go through every element in the array, and check if
there is a corresponding "<array_element>_added" variable.

perldoc -q "variable name" explains why this is a bad idea (it's
actually impossible for 'my' variables, short of using deep magic like
PadWalker). What are you actually trying to do?

Ben
 
R

RedGrittyBrick

Tomasz said:
I have a couple of variables, like:

my $thing_added = "test1";
my $otherthing_added = "test2";


I also have an array:

@array = ("thing", "otherthing", "no_such_variable");


Now, I would like to go through every element in the array, and check if
there is a corresponding "<array_element>_added" variable.


For example, for "thing", I would like to check if there is a
$thing_added variable. This should evaluate true, as I defined that
variable earlier.

Similarly, for "otherthing", I would like to check if there is a
$otherthing_added variable. This one should also evaluate true.

For "no_such_variable" element, a check for $no_such_variable_added
should evaluate false, as this variable was not defined.


I tried using "eval" to construct a variable out of yet another variable
value and a "_added" word, but haven't been successful.

Any hints?
$ perl -e '$x=foo; $foo=1; print defined($$x)?"Yes\n":"No\n"'
Yes

$ perl -e '$x=foo; $foo=0; print defined($$x)?"Yes\n":"No\n"'
Yes

$ perl -e '$x=foo; $bar=0; print defined($$x)?"Yes\n":"No\n"'
No

But IMHO you really really should be using hashes. Something not
entirely unlike:

my $thingies{thing_added} = "test1";
my $thingies{otherthing_added} = "test2";
...
for (@array) {
if (defined($thingies{$_})) {
...
}
}
(untested - caveat emptor)

I'm sure there's a FAQ that advises against the $$x kind of crazy
foolishness.
 
B

Ben Morrow

Quoth RedGrittyBrick said:
$ perl -e '$x=foo; $foo=1; print defined($$x)?"Yes\n":"No\n"'
Yes

~% perl -le'
use strict;
my $x = "foo";
my $foo = 1;
print defined($$x) ? "Yes" : "No";'
Can't use string ("foo") as a SCALAR ref while "strict refs" in use
at -e line 5

~% perl -le'
my $x = "foo";
my $foo = 1;
print defined($$x) ? "Yes" : "No";'
No
I'm sure there's a FAQ that advises against the $$x kind of crazy
foolishness.

perldoc -q "variable name"

There's also 'use strict', which forbids it entirely.

Ben
 
T

Tomasz Chmielewski

Josef said:
Tomasz Chmielewski wrote:
(...)


Every time you want to use variables as part of variable names, you're
better off using a hash.

Usually you save your life by using a hash as you usually get stoned to
death by asking these kinds of questions here.

Ha ha, I take it as a good advice for the future then :)
 
T

Tomasz Chmielewski

Ben said:
perldoc -q "variable name" explains why this is a bad idea (it's
actually impossible for 'my' variables, short of using deep magic like
PadWalker). What are you actually trying to do?

I have a couple of such "ifs", and they differ only slightly:


if ($product_id_added == 0 && length $product_id) {
&add_params("product_id", $product_id, $lun, $driver);
}


if ($vendor_id_added == 0 && length $vendor_id) {
&add_params("vendor_id", $vendor_id, $lun, $driver);
}



I thought of replacing these all "ifs" which differ only slightly by
going through array elements, and replacing each part.

my @array = ("product_id", "vendor_id", ...)

But it looks like I have to rethink that approach.
 
J

Jürgen Exner

Tomasz Chmielewski said:
I have a couple of variables, like:
my $thing_added = "test1";
my $otherthing_added = "test2";

I also have an array:
@array = ("thing", "otherthing", "no_such_variable");

Now, I would like to go through every element in the array, and check if
there is a corresponding "<array_element>_added" variable. [...]
Any hints?

Short answer: don't do that, it is A Bad Idea (TM).
Longer answer: you are looking for symbolic references. Please see the
history of this NG as well as the FAQ ("variable as a variable name")
why that is not a good idea.
Yet longer answer: Use a hash, dude, that's what they are for.

my %added;
$added{'thing'} = 'test1';
$added{'otherthing'} = 'test2';
.....
if (exists($added{'thing'})) {
print "Someone has added 'thing' to \%added";
}

jue
 
J

Joost Diepenmaat

Tomasz Chmielewski said:
I have a couple of such "ifs", and they differ only slightly:


if ($product_id_added == 0 && length $product_id) {
&add_params("product_id", $product_id, $lun, $driver);
}


if ($vendor_id_added == 0 && length $vendor_id) {
&add_params("vendor_id", $vendor_id, $lun, $driver);
}



I thought of replacing these all "ifs" which differ only slightly by
going through array elements, and replacing each part.

my @array = ("product_id", "vendor_id", ...)

But it looks like I have to rethink that approach.

You should. If you choose the right datastructure, you can probably
reduce the amount of code a lot more than if you "just" use symbolic
references here and there.

Also, it looks like you're using 2 flags to mark if something was
added. You won't need to if you're using a hash:

my %added;

# add a vendor id
$added{vendor} = 2;

# don't do anything with products

for my $key (qw(vendor products foo)) {
next unless exists $added{$key};
add_params("${key}_id",$added{$key},...)
}

also: IMHO it's bad style to use the &foo() construct to call
functions. foo() is a little shorted and has less potential problems.
 
T

Tomasz Chmielewski

Joost said:
You should. If you choose the right datastructure, you can probably
reduce the amount of code a lot more than if you "just" use symbolic
references here and there.

Also, it looks like you're using 2 flags to mark if something was
added. You won't need to if you're using a hash:

my %added;

# add a vendor id
$added{vendor} = 2;

# don't do anything with products

for my $key (qw(vendor products foo)) {
next unless exists $added{$key};
add_params("${key}_id",$added{$key},...)
}

Thanks for the tip.

also: IMHO it's bad style to use the &foo() construct to call
functions. foo() is a little shorted and has less potential problems.

Besides being "bad style", what potential problems can it make? (code
readability? something else?)
 
J

Jürgen Exner

Tomasz Chmielewski said:
Besides being "bad style", what potential problems can it make? (code
readability? something else?)

Do you know what the & does in a function call? It is not for decoration
but it does have an actual functionality, after all.

If you don't want to use prototypes then just don't use them. Most
people don't use them.
But declaring prototypes (don't know if you did, you didn't show us the
declaration of add_params) and then explicitely surpressing the
prototype check for every single function call is just plain stupid.

It's like installing a new electrical pump at your well but still using
the old bucket, only now you have to work your way around the suction
hose which is in the way.

jue
 
R

RedGrittyBrick

Tomasz said:
Besides being "bad style", what potential problems can it make? (code
readability? something else?)

See perldoc perlsub. It circumvents prototypes and causes current @_ to
be visible to the called subroutine. In 99% of cases you don't want this.

Using the &sub call notation was common in Perl 4 days but IIRC that was
superseded back in 1993, more than fifteen years ago.

Presumably you are learning Perl from something that is 15 years out of
date.
 
S

Sherm Pendley

Tomasz Chmielewski said:
Besides being "bad style", what potential problems can it make?

& was the norm for Perl 4. It's still supported for compatibility, but
it has side-effects that you probably don't want when you're writing
new code. It circumvents prototypes, and it doesn't localize @_ for
arguments.

In general, if you don't know whether you need to use &foo(), then you
don't need to. Its uses are few and very specific.

Have a look at 'perldoc perlsub' for details.

sherm--
 
J

Joost Diepenmaat

RedGrittyBrick said:
See perldoc perlsub. It circumvents prototypes and causes current @_
to be visible to the called subroutine. In 99% of cases you don't want
this.

Exactly, but note that passing on @_ only happens if you don't specify
parentheses and no arguments, like this:

sub mything {
my ($arg) = @_;
&something_else; # this passes on @_ to something_else
}
Using the &sub call notation was common in Perl 4 days but IIRC that
was superseded back in 1993, more than fifteen years ago.

Presumably you are learning Perl from something that is 15 years out
of date.

I would think so too.
 
M

mad_ady

Here is why $dynamicVariableName is a bad idea; it will convince you
to switch to hashes:
http://perl.plover.com/varvarname.html

The short reason, quoted from the text:
The real problem is that if your string contains something unexpected,
it will sabotage a totally unrelated part of the program, and then you
will have one hell of a time figuring out the bug.

Cheers.
 

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

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top