Loading ...
Sorry, an error occurred while loading the content.

Re: [MP2] eval and exit(0)

Expand Messages
  • Stas Bekman
    ... You don t need to load anything. Indeed under mp2: *CORE::GLOBAL::exit = &ModPerl::Util::exit; And you don t need to load anything for this to work. in
    Message 1 of 10 , Apr 29 10:28 AM
    View Source
    • 0 Attachment
      ydnar wrote:
      > The eval() is unecessary. The named sub can be used:
      >
      > &$func();
      >
      > mod_perl remaps exit() to ModPerl::Util::exit(). Are you sure the right
      > modules are being loaded?

      You don't need to load anything. Indeed under mp2:

      *CORE::GLOBAL::exit = \&ModPerl::Util::exit;

      And you don't need to load anything for this to work.

      in mp2 exit is implemented via a special die() call, therefore if you call it
      inside eval { } block (and eval "STRING" behaves identically) an exception is
      being thrown, but caught by eval.

      So in your case you either need to rethrow it:

      use ModPerl::Util qw(exit);
      my $func = 'first';
      eval "\&$func";
      exit if $@;
      &second();

      or use the CORE::exit:

      sub first {
      ...
      CORE::exit(0);
      }

      the problem with the latter is that it kills the process (or the interpreter
      if under threads), but it'll behave like mod_cgi and work the same under mod_cgi.

      So choose your poison.

      Also you can write your own exit function which will do what you want if
      neither of the two is satisfactory.

      __________________________________________________________________
      Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
      http://stason.org/ mod_perl Guide ---> http://perl.apache.org
      mailto:stas@... http://use.perl.org http://apacheweek.com
      http://modperlbook.org http://apache.org http://ticketmaster.com

      --
      Report problems: http://perl.apache.org/bugs/
      Mail list info: http://perl.apache.org/maillist/modperl.html
      List etiquette: http://perl.apache.org/maillist/email-etiquette.html
    • Arnaud Blancher
      ... yes but not with use strict ... for me, both solution don t work :-(( maybe me installation is wrong ... the output is always the sum of &first &second ...
      Message 2 of 10 , Apr 30 3:15 AM
      View Source
      • 0 Attachment
        Stas Bekman a écrit :

        > ydnar wrote:
        >
        >> The eval() is unecessary. The named sub can be used:
        >>
        >> &$func();
        >
        yes but not with
        use strict
        ...

        >>
        >>
        >> mod_perl remaps exit() to ModPerl::Util::exit(). Are you sure the
        >> right modules are being loaded?
        >
        >
        > You don't need to load anything. Indeed under mp2:
        >
        > *CORE::GLOBAL::exit = \&ModPerl::Util::exit;
        >
        > And you don't need to load anything for this to work.
        >
        > in mp2 exit is implemented via a special die() call, therefore if you
        > call it inside eval { } block (and eval "STRING" behaves identically)
        > an exception is being thrown, but caught by eval.


        for me, both solution don't work :-((
        maybe me installation is wrong ...
        the output is always the sum of &first &second

        >
        > So in your case you either need to rethrow it:
        >
        > use ModPerl::Util qw(exit);
        > my $func = 'first';
        > eval "\&$func";
        > exit if $@;
        > &second();


        #!/usr/bin/perl
        use strict;
        use CGI qw(:standard);

        # &first();
        my $func = 'first';
        eval "\&$func";
        # northing is print !
        # print "$@<br>";
        exit if $@;

        &second();

        sub first {
        print header();
        print "In first<br>";
        exit(0);
        }

        sub second {
        print "In second<br>";
        print "I dont want to see this part !";
        }

        1;


        =pod

        # in standad cgi, the output is

        In first

        # in mod_perl, the output is

        In first
        In second
        I dont want to see this part !

        # nothing in erreur log

        =cut


        >
        > or use the CORE::exit:
        >
        > sub first {
        > ...
        > CORE::exit(0);
        > }


        #!/usr/bin/perl

        use strict;
        use CGI qw(:standard);

        use ModPerl::Util qw(exit);
        my $func = 'first';
        eval "\&$func";
        # nothing is print !
        # print "$@<br>";
        exit if $@;
        &second();

        sub first {
        print header();
        print "In first<br>";
        exit(0);
        }

        sub second {
        print "In second<br>";
        print "I dont want to see this part !";
        }

        1;
        =pod

        # in standad cgi, don't work (of course of use ModPerl::Util)

        # in mod_perl, the output is

        In first
        In second
        I dont want to see this part !

        # nothing in erreur log

        =cut


        >
        > the problem with the latter is that it kills the process (or the
        > interpreter if under threads), but it'll behave like mod_cgi and work
        > the same under mod_cgi.
        >
        > So choose your poison.
        >
        > Also you can write your own exit function which will do what you want
        > if neither of the two is satisfactory.
        >


        Arnaud


        --
        Report problems: http://perl.apache.org/bugs/
        Mail list info: http://perl.apache.org/maillist/modperl.html
        List etiquette: http://perl.apache.org/maillist/email-etiquette.html
      • Stas Bekman
        ... try: { no strict refs ; &$func(); } FWIW, I find $func- () to be a more readable syntax. ... You mean one solution. Indeed, I tried it and it doesn t,
        Message 3 of 10 , Apr 30 11:33 AM
        View Source
        • 0 Attachment
          Arnaud Blancher wrote:
          > Stas Bekman a écrit :
          >
          >> ydnar wrote:
          >>
          >>> The eval() is unecessary. The named sub can be used:
          >>>
          >>> &$func();
          >>
          >>
          > yes but not with
          > use strict
          > ...

          try:

          {
          no strict 'refs';
          &$func();
          }

          FWIW, I find $func->() to be a more readable syntax.


          >> You don't need to load anything. Indeed under mp2:
          >>
          >> *CORE::GLOBAL::exit = \&ModPerl::Util::exit;
          >>
          >> And you don't need to load anything for this to work.
          >>
          >> in mp2 exit is implemented via a special die() call, therefore if you
          >> call it inside eval { } block (and eval "STRING" behaves identically)
          >> an exception is being thrown, but caught by eval.
          >
          >
          >
          > for me, both solution don't work :-((
          > maybe me installation is wrong ...
          > the output is always the sum of &first &second

          You mean one solution. Indeed, I tried it and it doesn't, since $@ is set to
          '', which is the same as if eval {} didn't die.

          You didn't try the second solution: CORE::exit(0), but you probably don't want
          to use it as it's not efficient. But it'll work exactly as mod_cgi does.

          I consider the inability to exit when called from eval as a problem, so we
          need to think of finding a better way to emulate exit-but-don't-exit
          functionality.

          __________________________________________________________________
          Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
          http://stason.org/ mod_perl Guide ---> http://perl.apache.org
          mailto:stas@... http://use.perl.org http://apacheweek.com
          http://modperlbook.org http://apache.org http://ticketmaster.com

          --
          Report problems: http://perl.apache.org/bugs/
          Mail list info: http://perl.apache.org/maillist/modperl.html
          List etiquette: http://perl.apache.org/maillist/email-etiquette.html
        • Arnaud Blancher
          ... yes, it s work. i don t realy like this solution, just because i always try to use use strict to avoid problem with mod_perl !!!! so, could you tell me
          Message 4 of 10 , May 3, 2004
          View Source
          • 0 Attachment
            Stas Bekman a écrit :

            > Arnaud Blancher wrote:
            >
            >> Stas Bekman a écrit :
            >>
            >>> ydnar wrote:
            >>>
            >>>> The eval() is unecessary. The named sub can be used:
            >>>>
            >>>> &$func();
            >>>
            >>>
            >>>
            >> yes but not with
            >> use strict
            >> ...
            >
            >
            > try:
            >
            > {
            > no strict 'refs';
            > &$func();
            > }


            yes, it's work.
            i'don't realy like this solution, just because i always try to use 'use
            strict'
            to avoid problem with mod_perl !!!!

            so, could you tell me if the final mp2, will have a solution for exit in
            eval function ?
            in this case i'll wait and keep my complete 'use strict'
            in the other case .. may be i will change all my script, and lost a part
            of 'strict'.


            Thanks
            Arnaud.


            >
            > FWIW, I find $func->() to be a more readable syntax.
            >
            >
            >>> You don't need to load anything. Indeed under mp2:
            >>>
            >>> *CORE::GLOBAL::exit = \&ModPerl::Util::exit;
            >>>
            >>> And you don't need to load anything for this to work.
            >>>
            >>> in mp2 exit is implemented via a special die() call, therefore if
            >>> you call it inside eval { } block (and eval "STRING" behaves
            >>> identically) an exception is being thrown, but caught by eval.
            >>
            >>
            >>
            >>
            >> for me, both solution don't work :-((
            >> maybe me installation is wrong ...
            >> the output is always the sum of &first &second
            >
            >
            > You mean one solution. Indeed, I tried it and it doesn't, since $@ is
            > set to '', which is the same as if eval {} didn't die.
            >
            > You didn't try the second solution: CORE::exit(0), but you probably
            > don't want to use it as it's not efficient. But it'll work exactly as
            > mod_cgi does.
            >
            > I consider the inability to exit when called from eval as a problem,
            > so we need to think of finding a better way to emulate
            > exit-but-don't-exit functionality.




            --
            Report problems: http://perl.apache.org/bugs/
            Mail list info: http://perl.apache.org/maillist/modperl.html
            List etiquette: http://perl.apache.org/maillist/email-etiquette.html
          • Stas Bekman
            Arnaud Blancher wrote: [...] ... But in this case, it disables strict refs only for a very small scope! It doesn t affect anything else, so you perfectly fine.
            Message 5 of 10 , May 3, 2004
            View Source
            • 0 Attachment
              Arnaud Blancher wrote:
              [...]
              >> try:
              >>
              >> {
              >> no strict 'refs';
              >> &$func();
              >> }
              >
              > yes, it's work.
              > i'don't realy like this solution, just because i always try to use 'use
              > strict'
              > to avoid problem with mod_perl !!!!

              But in this case, it disables strict refs only for a very small scope! It
              doesn't affect anything else, so you perfectly fine.

              > so, could you tell me if the final mp2, will have a solution for exit in
              > eval function ?
              > in this case i'll wait and keep my complete 'use strict'
              > in the other case .. may be i will change all my script, and lost a part
              > of 'strict'.

              I have a working solution (haven't committed yet), but I'm not 100% sure yet
              that it's going to stay, I have received no feedback so far on this proposal [1].

              At the moment looks like:

              use ModPerl::Const -compile => 'EXIT';

              eval {
              my $whatever = 1;
              exit();
              };
              exit if $@ && ref $@ && $@ == ModPerl::EXIT;

              The same will work for eval $string.

              What happens here is that exit calls die with an exception object, which you
              can observe outside the eval block (the numerical context of $@ will return
              ModPerl::EXIT value) and rethrow exit (or do return or else) to cleanly quit
              the handler w/o killing the process.

              If you wish, you can get the current cvs, apply my patch [1] and try the
              thing. You can see t/response/TestModperl/exit.pm which exercises this
              functionality.

              [1] http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=108354831109582&w=2

              __________________________________________________________________
              Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
              http://stason.org/ mod_perl Guide ---> http://perl.apache.org
              mailto:stas@... http://use.perl.org http://apacheweek.com
              http://modperlbook.org http://apache.org http://ticketmaster.com

              --
              Report problems: http://perl.apache.org/bugs/
              Mail list info: http://perl.apache.org/maillist/modperl.html
              List etiquette: http://perl.apache.org/maillist/email-etiquette.html
            • Glenn
              ... As Stas mentioned previously, you should be using coderefs: $func- () instead of eval() with &$func(). If you use eval () with &$func(), then I think you
              Message 6 of 10 , May 3, 2004
              View Source
              • 0 Attachment
                On Mon, May 03, 2004 at 07:17:54PM +0200, Arnaud Blancher wrote:
                > Stas Bekman a ?crit :
                >
                > >Arnaud Blancher wrote:
                > >
                > >>Stas Bekman a ?crit :
                > >>
                > >>>ydnar wrote:
                > >>>
                > >>>>The eval() is unecessary. The named sub can be used:
                > >>>>
                > >>>>&$func();
                > >>>
                > >>>
                > >>>
                > >>yes but not with
                > >> use strict
                > >>...
                > >
                > >
                > >try:
                > >
                > > {
                > > no strict 'refs';
                > > &$func();
                > > }
                >
                >
                > yes, it's work.
                > i'don't realy like this solution, just because i always try to use 'use
                > strict'
                > to avoid problem with mod_perl !!!!

                As Stas mentioned previously, you should be using coderefs: $func->()
                instead of eval() with &$func(). If you use eval () with &$func(),
                then I think you are bypassing some compile-time 'strict' checks on
                that code. If you want the compiler to enforce maximum strictness
                (a good thing), and you always try to 'use strict', as you say above,
                then you should be using coderefs instead of &$func(). An example
                will better illustrate proper usage:

                e.g. if you have the subroutines

                sub routine_1 { ... }
                sub routine_2 { ... }

                then instead of doing:

                my $func = 'routine_1';
                [ ... ]
                &$func();

                try the following:

                my $func = \&routine_1;
                [ ... ]
                $func->();

                That will compile cleanly with 'strict' in effect.

                If you do not know the routine name in advance, then you can
                create a hash of 'routine_name' => coderef and look up the
                routines to get the proper coderef:

                %valid_routines = ('routine_1'=>\&routine_1, 'routine_2'=>\&routine_2);

                $func = $valid_routines{$routine_name} || die "invalid routine name";

                OT for the mod_perl list, but HTH.
                Cheers,
                Glenn

                > so, could you tell me if the final mp2, will have a solution for exit in
                > eval function ?
                > in this case i'll wait and keep my complete 'use strict'
                > in the other case .. may be i will change all my script, and lost a part
                > of 'strict'.
                >
                >
                > Thanks
                > Arnaud.
                >
                >
                > >
                > >FWIW, I find $func->() to be a more readable syntax.
                > >
                > >
                > >>>You don't need to load anything. Indeed under mp2:
                > >>>
                > >>> *CORE::GLOBAL::exit = \&ModPerl::Util::exit;
                > >>>
                > >>>And you don't need to load anything for this to work.
                > >>>
                > >>>in mp2 exit is implemented via a special die() call, therefore if
                > >>>you call it inside eval { } block (and eval "STRING" behaves
                > >>>identically) an exception is being thrown, but caught by eval.
                > >>
                > >>
                > >>
                > >>
                > >>for me, both solution don't work :-((
                > >>maybe me installation is wrong ...
                > >>the output is always the sum of &first &second
                > >
                > >
                > >You mean one solution. Indeed, I tried it and it doesn't, since $@ is
                > >set to '', which is the same as if eval {} didn't die.
                > >
                > >You didn't try the second solution: CORE::exit(0), but you probably
                > >don't want to use it as it's not efficient. But it'll work exactly as
                > >mod_cgi does.
                > >
                > >I consider the inability to exit when called from eval as a problem,
                > >so we need to think of finding a better way to emulate
                > >exit-but-don't-exit functionality.
                >
                >
                >
                >
                > --
                > Report problems: http://perl.apache.org/bugs/
                > Mail list info: http://perl.apache.org/maillist/modperl.html
                > List etiquette: http://perl.apache.org/maillist/email-etiquette.html

                --
                Report problems: http://perl.apache.org/bugs/
                Mail list info: http://perl.apache.org/maillist/modperl.html
                List etiquette: http://perl.apache.org/maillist/email-etiquette.html
              • Stas Bekman
                ... Good point, Glenn. But it s actually not the style: &$func() and $func- () are the same strictness-checking-wise. but the coderef vs. eval string that
                Message 7 of 10 , May 3, 2004
                View Source
                • 0 Attachment
                  Glenn wrote:
                  > On Mon, May 03, 2004 at 07:17:54PM +0200, Arnaud Blancher wrote:
                  >
                  >>Stas Bekman a ?crit :
                  >>
                  >>
                  >>>Arnaud Blancher wrote:
                  >>>
                  >>>
                  >>>>Stas Bekman a ?crit :
                  >>>>
                  >>>>
                  >>>>>ydnar wrote:
                  >>>>>
                  >>>>>
                  >>>>>>The eval() is unecessary. The named sub can be used:
                  >>>>>>
                  >>>>>>&$func();
                  >>>>>
                  >>>>>
                  >>>>>
                  >>>>yes but not with
                  >>>>use strict
                  >>>>...
                  >>>
                  >>>
                  >>>try:
                  >>>
                  >>> {
                  >>> no strict 'refs';
                  >>> &$func();
                  >>> }
                  >>
                  >>
                  >>yes, it's work.
                  >>i'don't realy like this solution, just because i always try to use 'use
                  >>strict'
                  >>to avoid problem with mod_perl !!!!
                  >
                  >
                  > As Stas mentioned previously, you should be using coderefs: $func->()
                  > instead of eval() with &$func(). If you use eval () with &$func(),
                  > then I think you are bypassing some compile-time 'strict' checks on
                  > that code. If you want the compiler to enforce maximum strictness
                  > (a good thing), and you always try to 'use strict', as you say above,
                  > then you should be using coderefs instead of &$func(). An example
                  > will better illustrate proper usage:
                  >
                  > e.g. if you have the subroutines
                  >
                  > sub routine_1 { ... }
                  > sub routine_2 { ... }
                  >
                  > then instead of doing:
                  >
                  > my $func = 'routine_1';
                  > [ ... ]
                  > &$func();
                  >
                  > try the following:
                  >
                  > my $func = \&routine_1;
                  > [ ... ]
                  > $func->();
                  >
                  > That will compile cleanly with 'strict' in effect.
                  >
                  > If you do not know the routine name in advance, then you can
                  > create a hash of 'routine_name' => coderef and look up the
                  > routines to get the proper coderef:
                  >
                  > %valid_routines = ('routine_1'=>\&routine_1, 'routine_2'=>\&routine_2);
                  >
                  > $func = $valid_routines{$routine_name} || die "invalid routine name";

                  Good point, Glenn. But it's actually not the style:

                  &$func() and $func->() are the same strictness-checking-wise.

                  but the coderef vs. eval "string" that makes the difference. You can just as
                  well do:

                  perl -wle 'use strict; sub foo { print "X" }; my $func = \&foo; &$func'
                  X

                  It's personal preference of whether to use $func->() vs &$func, with an added
                  potential pitfall of &$func passing @_ along to the $func function, when ()
                  are forgotten. I prefer $func->() since it's clear that no arguments are
                  passed. It's not clear in this code:

                  use strict;
                  sub foo { print @_ };
                  sub bar {
                  my $func = \&foo;
                  &$func;
                  };
                  bar("a")'

                  as you can see it prints "a", which you may not expect from &$func, unless you
                  remember that &foo is special (this feature is there for 'goto &foo'
                  constructs usually used in AUTOLOAD).

                  On the other hand:

                  sub bar {
                  my $func = \&foo;
                  $func->();
                  };

                  prints nada. and you can clearly see that no args are passed.

                  Certainly, you could write:

                  sub bar {
                  my $func = \&foo;
                  &$func();
                  };

                  and @_ won't be passed, but you may forget to add (), you can't forget them in
                  $func->(). :)

                  --
                  __________________________________________________________________
                  Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                  http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                  mailto:stas@... http://use.perl.org http://apacheweek.com
                  http://modperlbook.org http://apache.org http://ticketmaster.com

                  --
                  Report problems: http://perl.apache.org/bugs/
                  Mail list info: http://perl.apache.org/maillist/modperl.html
                  List etiquette: http://perl.apache.org/maillist/email-etiquette.html
                Your message has been successfully submitted and would be delivered to recipients shortly.