Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

G'day djerius,

One of the main reasons for avoiding the use of 'string eval' is that it doesn't provide compile time warnings. If you use a BEGIN block, you can get around this.

BEGIN { my @yaml_classes = qw{YAML::XS YAML::Syck YAML::Tiny YAML}; first { eval "use $_; 1" } @yaml_classes or die "Unable to load any of these YAML classes: @yaml_classe +s"; }

That will give a compile time warning which, is not only very obvious with respect to the problem, but also will obviate the need for any specific testing to check if a YAML class was found and loaded, i.e. Test::More's use_ok('Your::Module::Name'), which I'd hope you already have, would suffice.

Unable to load any of these YAML classes: YAML::XS YAML::Syck YAML::Ti +ny YAML at ... BEGIN failed--compilation aborted at ...

If you need to know which YAML class was loaded and, as your code suggests, this is stored in a variable with package scope, I'd recommend something other than the all-too-common $class. You'd need to declare that variable outside the BEGIN block.

my $yaml_class; BEGIN { my @yaml_classes = qw{YAML::XS YAML::Syck YAML::Tiny YAML}; $yaml_class = first { eval "use $_; 1" } @yaml_classes or die "Unable to load any of these YAML classes: @yaml_classe +s"; } print $yaml_class;
"My module doesn't care which YAML is around, just that it can Dump and Load."

I'd probably consider testing for that in the BEGIN block also. The following example clearly documents the intent and would only need a change, in a single and obvious place (i.e. near the top of the module code), if that requirement ever changed.

BEGIN { # YAML classes to attempt to load (in order of preference) my @yaml_classes = qw{YAML::XS YAML::Syck YAML::Tiny YAML}; # Expecting to import these functons from whatever YAML class is l +oaded my @yaml_imports = qw{Dump Load}; my $yaml_class = first { eval "use $_ (\@yaml_imports); 1" } @yaml +_classes or die "Unable to load any of these YAML classes: @yaml_classe +s", " (using import list: @yaml_imports)"; }

Update (improved solution): I've changed that final BEGIN block (i.e. the changes are in the block immediately above here).

After posting, I realised that the original solution (see spoiler below) had some drawbacks: it loaded the YAML class before checking @EXPORT; it didn't allow imports from @EXPORT_OK; and, it would fail for all @yaml_classes if any particular class successfully loaded but then failed the @EXPORT test. The "improved solution" has none of these problems.

As already stated (i.e. "original solution (see spoiler below)"), but apparently not clear to some, I repeat, the original solution is hidden in the spoiler below.

[Minor Update: I've added some additional text, to the "Update (improved solution)" text, to make it clear that the original code is hidden in the spoiler.]

-- Ken


In reply to Re: What's the best way to use Any YAML (not YAML::Any) by kcott
in thread What's the best way to use Any YAML (not YAML::Any) by djerius

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2024-04-18 23:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found