in reply to Follow up to RFC: Templating without a System

require returns the last evaluated expression of a required file

No, that is only true the /first/ time that a file is required. I agree that it would be very nice if Perl allowed require (and use) to return something useful (in particular, a 'factory' that defaults to just the package name). But that isn't the case yet, even though it may appear that way if you do incomplete testing.

- tye        

  • Comment on Re: Follow up to RFC: Templating without a System (required)

Replies are listed 'Best First'.
Re^2: Follow up to RFC: Templating without a System (required)
by shmem (Chancellor) on Jul 01, 2006 at 15:30 UTC
    That is no great deal since the requiring is done only once. The package holds a lexically scoped hash of anonymous subs keyed on the filename. On a second call of servlet with a specific filename that sub is returned and can be used; the generated whatever.al must not be required twice - except on code change of the source. That is what the timestamp checking is about: if the source file is newer, the file is deleted from %INC and is thus required again. The new sub overwrites the old one. In short, this happens:
    package Foo; $f = 'testsub.pl'; $s = eval "require $f"; delete $INC{$f}; $t = eval "require $f"; print "$_\n" for ($s,$t); __END__ CODE(0x8167948) CODE(0x81679a8)
    And yes, I have to write a testsuite. (is there a leak?)
    And yes, having a synopsis to talk about would be nice.

    I'll update the code in the previous post sometime really soon (today or tomorrow).

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      So, not only are you using an undocumented feature of require, but you are also using it in a manner contrary to its purpose. In a code review, I'd reject such use unless you documented and enforced your unusual requirements. That is, you should check %INC before requireing so you can report that the file got required already (and include a comment about why that matters and that the feature of require that you are depending on is not documented).

      Even better, Perl already has a tool that does what you are using require for: do $file. Use that instead.

      - tye        

        Right, I'll use do. It just does what I want.

        I have to use require for the same reasons AutoLoader uses require and not just do FILE. do FILE, when wrapped in a string eval

        my $sub = eval "package $package; do '$file'";
        doesn't set $@ outside the eval. require dies, do does not. $sub is just undef, nothing more, and all I can do is mumble "something went wrong while 'do $file' at line $foo" which ain't any good.

        I need require; requiring a file twice happens only at development time (or if you do funny things like generating template source on the fly and ask for trouble unless you know what you're doing); it provides for re-compiling on the fly and shortens turnaround time.

        I'll include an argument to the package's import() function - recompile_on_change - which will enable such behaviour, and note the implications prominently in the code and in the pod.

        Does that stand to your scrutiny?

        thanks for the hint again,

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      A reply falls below the community's threshold of quality. You may see it by logging in.