Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

how to goto &sysread ?

by perl5ever (Pilgrim)
on Jul 24, 2011 at 23:15 UTC ( [id://916452]=perlquestion: print w/replies, xml ) Need Help??

perl5ever has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to 'goto &sysread', the built-in perl function, but none of these work:
goto &sysread; goto &CORE::sysread; goto &CORE::GLOBAL::sysread;

Update: What's interesting is that you can replace the built-in definition of sysread with a sub, but you can't goto it.

Replies are listed 'Best First'.
Re: how to goto &sysread ?
by choroba (Cardinal) on Jul 24, 2011 at 23:22 UTC
    sysread is not a subroutine.
    $ perl -e '&sysread' Undefined subroutine &main::sysread called at -e line 1.
    See also: goto
Re: how to goto &sysread ?
by ikegami (Patriarch) on Jul 25, 2011 at 01:32 UTC
    sysread is an operator, not a subroutine. As such, it cannot replace the currently executing subroutine.
Re: how to goto &sysread ?
by Khen1950fx (Canon) on Jul 25, 2011 at 00:51 UTC
    I'll have to agree with Anonymous Monk---using goto is frowned upon; however, there are times when you want to "pretend". In that case, I'd use AutoLoader. Here's an example where I follow the docs:
    package Foo; use AutoLoader 'AUTOLOADER'; package Bar; use AutoLoader; AUTOLOAD(); print "OK...Done!\n" unless $@; __END__ sub AUTOLOAD { $AutoLoader::AUTOLOAD = "CORE::sysread", goto \&AutoLoader::AUTOLOAD; }
    Update: Fixed awkward language and &AUTOLOAD

      using goto is frowned upon

      Using goto to control flow is often frowned upon (even when it shouldn't be), but goto &name; doesn't do that.

      vthere are times when you want to pretend that you used a subroutine but didn't.

      goto &name; does the opposite. It removes a subroutine that did get called from the call stack.

Re: how to goto &sysread ?
by Marshall (Canon) on Jul 25, 2011 at 03:59 UTC
    I've read the replies so far. What you have written as proposed code is simply nonsense. doesn't make sense to me. Please explain in words what it is that you are trying to accomplish?

    You cannot "go to" a function x(), because there would be no way to return from the function. Part of a statement like: func_x(); is setting up the stack to call func_x() so that when func_x finishes, it returns to the caller. A "go to" would skip all that stuff that enables the function to return to the caller.

    Describe in words what you are trying to do.

    Update: this code example, while correct is not illustrative of the OP's problem.

    sysread() would be used for say reading a socket with fixed size user level packets. When we read the socket, we learn how many bytes were actually read and we loop if we need more. "Go to sysread() makes no sense".

    sub readn #returns scalar with <= $bytes requested { my ($socket, $bytes ) = @_; my $offset = 0; my $buf = ""; my $nread = -1; while ($offset < $bytes and $nread) # $nread==0 means EOF { my $nleft = $bytes-$offset; $nread = sysread($socket, $buf, $nleft, $offset); $offset += $nread; } return $buf; }

      goto &name is not nonsense at all. It's how Autoloader implements its AUTOLOAD() function. The design principle there (skipping over all the important details) is when Autoloader is triggered, AUTOLOAD can generate the requested (but not yet loaded) sub as a coderef, place a symbol for it in the symbol table, and then invoke goto &name as a means of invoking the actual function called without leaving any obvious trace in the call stack of all the Autoload trickery.

      This technique is discussed in detail in Simon Cozens' book, Advanced Perl Programming, 2nd Edition (O'Reilly).

      A quote from a "Tip" footnote in that book:

      goto LABEL and goto &subname are two completely different operations, unfortunately with the same name. The first is generally discouraged, but the second has no such stigma attached to it. It is identical to subname(@_) but with one important difference: the current stack frame is obliterated and replaced with the new subroutine.

      In the same book there is also a discussion on using the goto &name construct to create a wrapper for another function. Say you want to add some functionality to an existing function without having to reimplement the function, and you want to do it in a way that doesn't force you to invoke a new function name. You might do something like this:

      sub subA { print "You called subA\n"; } { my $oldsub = \&subA; my $wrap = sub { print "You called the wrapper around subA\n"; goto &$oldsub; }; *main::subA = $wrap; } subA(); __END__ You called the wrapper around subA You called subA

      Update: After considering the preceding example you might (as I did) suspect that you would find goto &name used in the autodie pragma as well... and as a matter of fact, the Fatal module that does the heavy lifting for autodie doesn't disappoint us; goto &name is an important part of how it works.

      Mark Jason Dominus's book Higher Order Perl, along with his Memoize module show another example of goto &name in action as a means of facilitating the memoize() function which wraps an existing function in a caching wrapper and passes the memoized version back to the symbol table for future use. goto makes it all easy, as well as almost invisible.


      Dave

      It's very simple...

      sysread() looks like a function/subroutine, and so I want to goto &sysread just like you would goto any other sub.

      However, as ikegami and others have pointed out, sysread() is not a sub, so I can't do that.

      Oh well...

        sub sysread { if (@_ == 4) { sysread($_[0], $_[1], $_[2], $_[3]) } elsif (@_ == 3) { sysread($_[0], $_[1], $_[2]) } else { croak("Bad usage") } } ... goto &sysread; ...
        There is not much difference between a function and a subroutine. Don't call subroutines with &suba syntax, use suba(); to mean that there are no arguments.

        I've seen the routine use of &subcallABC in very ancient (>10+ year old Perl code). Maybe this was the way a very long time ago to call a subroutine. Nowadays, this just means ignore the prototype for subcallABC when calling that sub.

        So, even if sysread() was a sub goto &sysread is wrong. You do not "jump" to subroutines, you "call" them. "Calling" means that we save our current place in the code with the intention of resuming where we left off, i.e. after the subroutine call.

        Simply put, you do not "goto" a function or a subroutine. You "call" the function or subroutine, which means: save my current place in the code and go do something and when that is done resume my code after this "call". If you "goto" or "jump" directly into some function's or subroutine's code, it will cause a crash because the preamble of "where to go back to when I am finished" was not done.

        Again, what do you want to do?

Re: how to goto &sysread ?
by Anonymous Monk on Jul 25, 2011 at 00:23 UTC
    And if this code is doing what I think it's doing .. uhh, you don't want to be doing that. No matter how "efficient" you think it is. You'll never be able to debug the damn thing in the field, and that's what makes it very, very bad code.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://916452]
Approved by davido
Front-paged by davido
help
Chatterbox?
and the web crawler heard nothing...

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

    No recent polls found