Re: help with a Perl term
by btrott (Parson) on Jun 08, 2000 at 06:52 UTC
|
eval has two purposes. If given an expression (EXPR), eval
will evaluate that expression as a small Perl program. This is
generally the form of eval that people term "evil," because it
delays execution of the code until runtime. And is thus slow.
Given a block (BLOCK), the block will be compiled at compile-time,
rather than run-time (as in the EXPR form).
If an error occurs in the expression/block that you're executing, the
error message will be in the $@ variable after your eval.
In other words, eval,
in combination with die, can be used as an exception mechanism
in Perl. For example, you can try to require a module in an
eval block, then check $@ (the "exception", in this case) to
see if the require has succeeded:
eval {
require LWP;
};
if ($@) {
die "Can't load LWP: $@";
}
| [reply] [d/l] |
|
|
If I understand you correctly, this may solve a problem I've been dealing with when I have scripts designed to work on NT and UNIX.
Would this work?
$is_NT = ($ENV{'OS'} eq 'Windows_NT');
if ($is_NT) {
eval { use Win32::ODBC; }
} else {
eval { use DBI; }
}
The problem exists because Win32 doesn't happen to be on my UNIX box. :) Is there another way to conditionally use a module?
| [reply] [d/l] |
|
|
That snippet doesn't do anything if the use() fails. And, what if it is NT but Win32::ODBC isn't installed? What if it is a Win32 system with DBI installed? How about:
eval { require DBI };
if ($@) {
warn "DBI not here.. will keep checking...";
}
eval { require Win32::ODBC };
if ($@) {
warn "Oh oh";
}
... etc...
or (ok, this is far fetched):
my %subs = ('DBI' => \&use_dbi,
'Win32::ODBC' => \&use_odbc,
'Win32::OLE' => \&use_ole
);
my @mods = ('DBI', 'Win32::ODBC', 'Win32::OLE');
for (@mods) {
eval { require $_ };
if ($@) {
warn "No $_ here";
}else{
$subs{$_}->();
last;
}
}
Cheers,
KM | [reply] [d/l] [select] |
|
|
Shendal, this is totally off the eval topic, but why not just stick with one flavor? I've used DBI on Win32 and UNIX, with great results (even porting from one to the other was great). Is there any specific reason why you would want to use Win32::ODBC instead of DBI? You'll have to change the connect string that creates the database handler anyway.
Just my R$0.02.
#!/home/bbq/bin/perl
# Trust no1!
| [reply] |
|
|
|
|
|
|
|
Out of curiosity, why would you eval the require, then die if the eval fails? If the require fails it would die anyways. Something like this makes a little more sense (to me):
my $bad;
BEGIN {
eval { require Foo };
if ($@) {
$bad = "Foo";
warn "This requires $bad to work. " .
"You can get it at ... ";
}
}
sub new {
return undef if $bad;
...etc...
}
Cheers,
KM | [reply] [d/l] |
|
|
| [reply] |
|
|
(jcwren) Re: help with a Perl term
by jcwren (Prior) on Jun 08, 2000 at 17:00 UTC
|
'eval' is an extremely powerful and dangerous construct, used in the wrong hands. One of the coolest things about it is that it can make an application (or Perl iteself) extensible, similiar to Forth.
Imagine a situation where you have a graphical calculator written in Perl. It has four basic functions: add, subtract, divide, multiply. You have a few extra buttons that users can assign functions to. By allowing them to enter an expression, you can create functions that previously didn't exist. You capture the user's function to a string, then 'eval' the string when it's time to use that key in a an expression. You've now extended the function of the calculator.
It's somewhat slow, since the 'eval' is done at run time instead of compile time, but it can be a neat way to implement otherwise difficult things. Of course, the peril should be obvious. You allow a user to enter something like`rm -rf /`eval that, and they've wiped the hard drive. Any input from users that's fed through 'eval' has to be fully qualified.
In Forth, you can do something that's even more powerful. The words you create become part of the language itself. You can create new words at compile time, or during run time. You think Perl obfusication can be hairy, try seeing some Forth that produces Forth code, compiles itself, runs itself, and then reproduces itself.
--Chris | [reply] [d/l] |
Re: help with a Perl term
by BigJoe (Curate) on Jun 08, 2000 at 06:59 UTC
|
eval runs a command or a set of commands. You can test data for its validity through this command. eval "$val= ; ";
if ( $@ eq "")
{ print "this is valid"; }
else
{ print "$@ is invalid"; }
It is a way to trap possible error conditions during run time. | [reply] [d/l] |
Re: help with a Perl term
by swiftone (Curate) on Jun 08, 2000 at 18:32 UTC
|
eval is a beautiful option is used correctly. Uses include:
- Checking for die conditions without die-ing
- Giving great user flexibility to specify options in config files. For example, I'm working with a program that has data files that are in essence miniature programs. The datafiles are loaded during run, and each mini-program will need to be executed many times. My solution? I translate the programs into perl when the file is loaded, and eval() them when I need to.
If you going to use eval with any user-specified data, it is a good idea to turn on taint-checking. See perlman:perlrun for -T, and perlman:perlsec for security concerns in perl. | [reply] |