Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Number of times I've used goto in Perl

by HugoNo1 (Novice)
on Sep 26, 2018 at 11:07 UTC ( [id://1223045]=note: print w/replies, xml ) Need Help??


in reply to Number of times I've used goto in Perl

Surprisingly nobody has commented on this nice use of the goto Function
which exists only in Perl:

sub newFuctionName { #Doing the same stuff as always ... } sub oldFunctionName { goto &newFuctionName; }

Which has the nice effect:
http://perldoc.perl.org/functions/goto.html

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

That way the Parameters won't be copied again when you go from oldFunctionName() to newFunctionName()
which is very useful when you use a Library in many Projects and by the time find that you should rename this Feature.

I also found this often in Modules as:

sub _internalImplementation { #Doing the job ... } sub exportFunctionName { goto &_internalImplementation; }

Replies are listed 'Best First'.
Re^2: Number of times I've used goto in Perl
by Eily (Monsignor) on Sep 26, 2018 at 13:01 UTC

    Well the people mentioning AUTOLOAD are actually talking about this version of goto. For example this post explicitly mentions goto &{ $AUTOLOAD };.

    The interest of goto isn't only about the fact that it transmits the current value of @_ to the called sub. Actually this is already the case when you do this:

    sub exportFunctionName { &_internalImplementation; }
    this is documented in perlsub
    If a subroutine is called using the & form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.
    Actually I'm pretty sure there was a post about goto being slower than a simple function call (because it has to exit the the local changes) but I couldn't find it.

    So the main interest of goto lies in the fact that it doesn't add a function to the calling stack but instead replaces the current one. This means that with this code:

    sub A { goto &_A; } sub _A { B(); }
    The B function will never see &A in the calling stack, but only &_A. This can be used for debbuging, when you want to call a wrapper function (to print "About to enter &function", or check the input). I remember this question where this was precisely what the OP asked for.

      According to the official Documentation on

      https://perldoc.perl.org/perlperf.html#Assigning-and-Dereferencing-Variables.
      > The difference is clear to see and the dereferencing approach is slower.

      Dereferencing Variables is slower than Passing the References through.

      Therefore a Code like:

      package MyClass1; sub newFunctionName { #Doing my stuff } sub oldFunctionName { my $self = shift; $self->newFunctionName(@_); }

      As you would do it in other Programming Languages. Will be slower than the goto Implementation:

      package MyClass2; sub newFunctionName { #Doing the stuff } sub oldFunctionName { goto &newFunctionName; }

      That is what I exactly was looking for but couldn't find any concrete Example for it.

      This makes Sense because in the MyClass1::oldFunctionName() implemention the $self variable must be created in memory first which consumes CPU Processing Time.
      Which is confirmed by the official Documentation.

        That doesn't contradict my point, which was that goto has 3 effects: transmitting @_ directly, removing the current function from the call stack and clearing the effect of local. If all you want to do is jump to another function without touching @_, this can be done like this:

        sub oldFunctionName { &newFunctionName; }
        I have quoted the relevant documentation in my previous post.

        Besides, since goto does this extra work, I wouldn't be confident about saying that it uses less CPU. Also perl does plenty of things under the hood, and the documentation calls it "magic". I would never conclude that a feature takes less CPU time based on the description of what it does alone.

        There is no dereferencing in your code though, dereferencing would like one of those lines:

        $$self; ${$self}; @{$self}; %{$self}; $self->{Key}; $self->[0];
        Sadly the syntax for a method call works only on (some) references, and also uses the arrow operator ( -> ) so it's quite confusing.

        87 core Perl (5.28.0) modules (out of 650) use goto 253 times:
        
        _charnames
        Archive::Tar
        attributes
        autodie
        autodie::Util
        AutoLoader
        AutoSplit
        autouse
        B
        B::Concise
        B::Deparse
        B::Op_private
        bytes
        Class::Struct
        Compress::Raw::Bzip2
        Compress::Raw::Zlib
        Config
        CPAN
        CPAN::Distribution
        DB_File
        Devel::Peek
        Devel::PPPort
        diagnostics
        DynaLoader
        Encode
        Exporter
        ExtUtils::CBuilder::Base
        ExtUtils::Command::MM
        ExtUtils::Constant
        ExtUtils::Liblist
        ExtUtils::MM_VMS
        Fatal
        fields
        File::Compare
        File::Copy
        File::DosGlob
        File::Glob
        File::Path
        File::stat
        Filter::Simple
        Getopt::Long
        Hash::Util
        if
        IO::Select
        IO::Socket::IP
        IO::Uncompress::Base
        IPC::SysV
        List::Util
        Locale::Codes::Language_Codes
        Memoize
        Module::Load
        mro
        Net::FTP
        Net::hostent
        Net::netent
        Net::protoent
        Net::servent
        ok
        Opcode
        open
        Pod::Functions
        Pod::Simple::BlackBox
        Pod::Simple::LinkSection
        POSIX
        SelfLoader
        sigtrap
        strict
        Sys::Syslog
        TAP::Parser
        TAP::Parser::Aggregator
        TAP::Parser::Result::Test
        Term::ANSIColor
        Term::Cap
        Test2::EventFacet::Meta
        Test2::IPC
        Test::Tester
        Test::Tester::Delegate
        Text::Balanced
        threads
        Tie::Memoize
        Time::HiRes
        Unicode::UCD
        User::grent
        User::pwent
        utf8
        warnings
        XSLoader
        
Re^2: Number of times I've used goto in Perl
by hippo (Bishop) on Sep 26, 2018 at 13:33 UTC

    Compare and contrast:

    #!/usr/bin/env perl use strict; use warnings FATAL => 'recursion'; my $i = 0; one(); sub one { print "$i\n" unless ++$i % 10; push @_, 'foo'; &one; }
    #!/usr/bin/env perl use strict; use warnings FATAL => 'recursion'; my $i = 0; one(); sub one { print "$i\n" unless ++$i % 10; push @_, 'foo'; goto &one; }

    Like much in the way of the Swiss Army Chainsaw you need to know precisely what you're doing if you run it with the guards off. Limbs can be easily lost.

      Hm ...

      ... is the goto version faster? Is this a way to have tail-recursion in Perl?

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        I'm pretty sure there was a detailed explanation of what makes goto slower (in most cases?) than a plain ⊂ call. But while searching for it I did end up finding this post and this answer. I would be tempted to guess that the function call with goto was more expensive (because of the extra magic to clear the local scope and play with the call stack), but the return was more efficient because it didn't require going back through all the calling stack (ie, tail recursion done right). I wouldn't rely on the result of benchmarks from 2005 for current versions of perl though :P

Re^2: Number of times I've used goto in Perl
by LanX (Saint) on Sep 26, 2018 at 11:37 UTC
    > Surprisingly nobody has commented on this nice use of the goto Function

    Because nobody wanted to miss the point?

    That's a very different kind of semantics which could easily be bound to another keyword like "call".

    Perl has many examples of multiple semantics, e.g. eval

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      I got a syntax error because of detail that I might have missed out.
      And I searched on Google about it, but I could not find anything suitable Example about the correct usage.

      Actually I'm doing you a favor to the PerlMonks and to Perl with documenting this usage with useful examples.

      > > Surprisingly nobody has commented on this nice use of the goto Function
      > Because nobody wanted to miss the point?

      https://www.perlmonks.org/?node_id=1208600
      So, I notice more and more why this statement

      • is true
      • was commented anonymously

Log In?
Username:
Password:

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

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

    No recent polls found