develooper Front page | perl.perl5.porters | Postings from May 2015

Re: Question/suggestion on perlfunc.pod example

Thread Previous | Thread Next
From:
Glenn Golden
Date:
May 12, 2015 00:59
Subject:
Re: Question/suggestion on perlfunc.pod example
Message ID:
20150512005857.GD581@huh.zplane.com
Aristotle Pagaltzis <pagaltzis@gmx.de> [2015-05-12 00:21:48 +0200]:
> * Glenn Golden <gdg@zplane.com> [2015-05-11 23:25]:
> > Regarding this example from perlfunc.pod, pertaining to "do":
> >
> >     ===================================================================
> >     for $file ("/share/prog/defaults.rc", "$ENV{HOME}/.someprogrc")
> >     {
> >         unless ($return = do $file) {
> >             warn "couldn't parse $file: $@" if $@;
> >             warn "couldn't do $file: $!"    unless defined $return;
> >             warn "couldn't run $file"       unless $return;
> >         }
> >     }
> >     ===================================================================
> 
> Wow, that’s bad.
> 
> > Is the final "unless $return" necessary?
> 
> No.
> 
> > Also: The meaning of the word 'run' in the warning text "couldn't run
> > $file" seems unclear. If my understanding of the accompanying doc text
> > is correct, seems like it should be possible to reach that warning
> > clause only if the final expression resulting from evaluating $file is
> > false. If this reading is correct, would it make sense to change the
> > warning text to something more directly interpretable by the reader,
> > e.g. "final expression evaluating $file is false"?
> 
> As far as the example goes, that would work. The apparent intent might
> be better expressed by "invalid configuration returned from $file".
> 
> But the example doesn’t make much sense. You can write a “configuration”
> file whose final expression yields undef and confuse it; as well, under
> several conditions it will display several warnings for the same file.
> 
> I *think* this untested code covers all the bases…
> 
>     for my $file ("/share/prog/defaults.rc", "$ENV{HOME}/.someprogrc") {
>         local ($!, $@);
>         $return = do $file or warn
>             ( $@                     ? "couldn't parse $file: $@"
>             : $! && !defined $return ? "couldn't do $file: $!"
>             :                          "invalid configuration returned from $file"
>             );
>     }
> 
> … but I’m not sure about $! and there may not be any unambiguous signal
> for that case available.
> 
> Also, $@ being set doesn’t point to a parsing error specifically – just
> an exception thrown at any point before the code in the file returned.
> So that message is wrong.
> 
> In short… that is one terrible example.
> 
> > If so, I'll be happy to submit a doc patch for either/both of these
> > changes, but wanted to first ask if my understanding of this was even
> > correct.
> 
> It doesn’t make sense to me to promote `do` as a configuration loader
> mechanism in the first place, not even in trying to contrive a use case
> for `do`. I’d go with a narrowly focused example, dumping the loop and
> rewording the error messages to purely problem-domain statements that
> describe each error condition precisely.
> 

OK. How about something straightforward like this then:

  ==================================================================
  if (not $r = do $file)
  {
      if ($@)
	    { warn "parse error or exception 'do'ing $file: $@"; }
      elsif ($! && not defined $r)
	    { warn "couldn't 'do' $file: $!";                    }
      else                     
	    { warn "invalid configuration returned from $file";  }
  }
  ==================================================================

As written above and tested lightly/naively, it seems to report the various
error conditions correctly, at least to my inexpert eye. I could easily be
missing something subtle.

However, for reasons I don't fully understand, when "local($!, $@)" is added
prior to "if ($@)" [i.e., mimicking what you had shown], and then running
it with a non-existent filename, it winds up taking the 'else' clause rather
than the expected 'elsif' clause with $! = "no such file or dir". 

What's going on with that? 

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About