http://qs321.pair.com?node_id=11111672


in reply to Eval/package question

You already got the answer from GrandFather, but here's another way to see what's happening:

print("$items{3}{Value} = 2;"); eval("$items{3}{Value} = 2;");
That way you'll see exactly what eval receives as an argument.

Why are you using eval in the first place? String eval means the code isn't compiled until the very last moment, so if you introduce some mistake like a syntax error, you wouldn't get notified until you execute the bit of code that contains the eval (which might not be everytime). If you're trying to catch errors, using a block eval (eval { $value =  2; }) lets perl compile the code rightaway, but only execute the section separately

Edit: corrected my code tags thanks to choroba's sharp vision :P

Replies are listed 'Best First'.
Re^2: Eval/package question
by Ratazong (Monsignor) on Jan 21, 2020 at 11:33 UTC

    Thanks a lot, GrandFather and Eily!

    I have a generic configuration in an Excel-file, and move it to several hashes by creating the commands as strings and eval-ing them. It works in my stand-alone-script, but doesn't any longer when moving the code into the package (the package variable (%items above) is not available). So my example above did not reproduce my issue - and I'll have to search further.

    Nevertheless, I learned something today :-)

    Have a great day, Rata

      I have a generic configuration in an Excel-file, and move it to several hashes by creating the commands as strings and eval-ing them.

      As others have mentioned, stringy eval is often not a good idea. Especially when working with hashes, what's wrong with the following?

      our %items; my $item = '3'; my $key = 'Value'; my $value = 2; $items{$item}{$key} = $value;
      (the package variable (%items above) is not available).

      It is not, because %items is declared as a my variable and thus available only in the the package itself, not in the main package.

      If you have to access it from main, you either have to fully qualify it as %items::items, or provide methods to access it (exporting it, providing accessors or a method which returns a reference to it, etc), but it's hard to say what's best without knowing the whole scenario.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

        my variables are local to the lexical scope in which they are declared, and can not be accessed outside that scope.

        If you want to access %items outside the file in which it is declared, you need to specify our %items, not my %items. Then you can access it by its fully-qualified name. That is, if it is declared in package Foo you say (e.g.) $Foo::items{Dent} = 'Arthur';.

        In an ideal world the OP would not be mucking around with global variables, but this is not an ideal world.

      I have a generic configuration in an Excel-file

      Have you considered exporting that as CSV and using Text::CSV to load the data?

      (Hint: Data::Dumper will tell you what you have at intermediate stages if you are unsure.)