Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^2: how to goto &sysread ?

by perl5ever (Pilgrim)
on Jul 25, 2011 at 05:19 UTC ( [id://916483]=note: print w/replies, xml ) Need Help??


in reply to Re: how to goto &sysread ?
in thread how to goto &sysread ?

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...

Replies are listed 'Best First'.
Re^3: how to goto &sysread ?
by ikegami (Patriarch) on Jul 25, 2011 at 05:31 UTC
    sub sysread { if (@_ == 4) { sysread($_[0], $_[1], $_[2], $_[3]) } elsif (@_ == 3) { sysread($_[0], $_[1], $_[2]) } else { croak("Bad usage") } } ... goto &sysread; ...
Re^3: how to goto &sysread ?
by Marshall (Canon) on Jul 25, 2011 at 05:39 UTC
    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?

      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.

      I'm not sure, but it could be that you don't know what goto(&func); does. goto(&func); is basically return &func;, except it tears down the current stack frame first.

      >perl -MCarp=confess -e"sub h { confess; } sub g { h(); } sub f { g(); + } f();" at -e line 1 main::h() called at -e line 1 main::g() called at -e line 1 main::f() called at -e line 1 >perl -MCarp=confess -e"sub h { confess; } sub g { goto &h; } sub f { +g(); } f();" at -e line 1 main::h() called at -e line 1 main::f() called at -e line 1

      It's perfectly safe.

      IIRC, goto(&func); is slower than return &func;, but it can save memory in deeply recursive functions. The main purpose is too fool Carp.

        Yes, you are correct. I was unaware of this.

        The goto-&NAME form is quite different from the other forms of goto. In fact, it isn't a goto in the normal sense at all, and doesn't have the stigma associated with other gotos. Instead, it exits the current subroutine (losing any changes set by local()) and immediately calls in its place the named subroutine using the current value of @_.

        It appears that this is sort of like an exec() at the subroutine level. That it can "fool" caller() is significant.

        In the process of thinking about the OP's question, I have learned something. But I'm still curious as to what the OP is trying to do? The above notwithstanding, what is the application?

        Apparently, which is slower depends on your version of perl... :-)

        Here's the benchmark code I used. Now, it's not entirely fair because I'm not testing with a long list of parameters - Benchmark is going to only pass in a single parameter. However, it's a start.

        #!/usr/bin/perl sub dest { return 1 } # don't want it optimised away use Benchmark qw(:all); cmpthese(-1, { goto => sub { goto &dest; }, call => sub { return dest(@_); }, callamp => sub { return &dest; }, });
        And the results? They depend on the version of perl. Using just the oldest and newest perls I have:
        $ perl5.8.8 x.pl Rate call callamp goto call 4283398/s -- -9% -29% callamp 4693114/s 10% -- -22% goto 5996757/s 40% 28% -- $ perl5.14.1 x.pl Rate call goto callamp call 4633858/s -- -9% -12% goto 5119310/s 10% -- -2% callamp 5242879/s 13% 2% --
        Of course, nothing of import is actually happening, the code in the called function will likely completely overwhelm the calling, so (and I'm sure you, ikegami, know this) don't base which one you use on the performance - there is no real significant difference - even the slowest one in perl 5.8.8 only takes 2.3e-7 seconds (on my CPU), which amounts to a couple hundred CPU cycles. Any REAL work you're doing will so completely overwhelm this that the so-called "savings" between calling it one way vs another will be nothing more than noise. Use the one that does what you mean, the maintainers (which likely will include yourself 6+ months from now) will thank you.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://916483]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-07-24 21:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.