PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Saturday, July 9, 2022

[FIXED] how can I invoke a subroutine reference generated from a string in perl?

 July 09, 2022     perl, reference, subroutine     No comments   

Issue

Several times in my code, I do the following.

  1. generate a path from the name of a subroutine
  2. invoke the subroutine and return a reference to what the subroutine created
  3. store the reference to the path.

I want to replace these blocks with a function, on the DRY: Don't repeat yourself principle. Thanks to Generating a subroutine reference from a string, I know how to generate a ref to an arbitrary subroutine inside dontrepeatyourself below. But when I try to invoke the arbitrary subroutine, I get

Can't use string ("doggy") as a subroutine ref while "strict refs" in use

Here is my code. writeeverythingtwice does the job but requires the user to type the sub name twice when invoking. What if the user fails to type the same name in both fields? Chaos and confusion and wasted time debugging.

Surely there is a way to invoke a subroutine inside dontrepeatyourself?

#!/usr/bin/env perl 
use strict; use warnings;
use Data::Dumper qw(Dumper); $Data::Dumper::Sortkeys = 1;
use feature 'say';

writeeverythingtwice(name=>'doggy',ref=>\&doggy,);
dontrepeatyourself(subname=>'doggy',);

sub dontrepeatyourself
{
    use Cwd 'abs_path'; use Storable;
    # https://stackoverflow.com/questions/30236740/generating-a-subroutine-reference-from-a-string
    my$whoiam= (caller(0))[3]; say 'you are now inside ',$whoiam;
    my$HOMEarg={@_};
    say ref \&{ $HOMEarg->{subname} };
    my $reftostore=\&{ $HOMEarg->{subname} }->(); # generates error
    my$path=abs_path('.') . '/' . $HOMEarg->{subname} . '.perlstorable' ;
    store($reftostore,$path);
    say 'we have stored to ',$path;
}

sub writeeverythingtwice
{
    use Cwd 'abs_path'; use Storable;
    # https://stackoverflow.com/questions/30236740/generating-a-subroutine-reference-from-a-string
    my$whoiam= (caller(0))[3]; say 'you are now inside ',$whoiam;
    my$HOMEarg={@_};
    my$path=abs_path('.') . '/' . $HOMEarg->{name} . '.perlstorable' ;
    my$reftostore=$HOMEarg->{ref}->();
    store($reftostore,$path);
    say 'we have stored to ',$path;
}

sub doggy
{
    my$whoiam= (caller(0))[3]; say 'you are now inside ',$whoiam;
    return [ 'foo','bar' ];
}



Solution

One answer, which requires an additional line of code, works as follows.

  1. Generate the ref to the sub
  2. save the ref to a new named variable
  3. invoke the sub from the new named variable.

Thus we have

#!/usr/bin/env perl 
use strict; use warnings;
use Data::Dumper qw(Dumper); $Data::Dumper::Sortkeys = 1;
use feature 'say';

writeeverythingtwice(name=>'doggy',ref=>\&doggy,);
dontrepeatyourself(subname=>'doggy',);

sub dontrepeatyourself
{
    use Cwd 'abs_path'; use Storable;
    # https://stackoverflow.com/questions/30236740/generating-a-subroutine-reference-from-a-string
    my$whoiam= (caller(0))[3]; say 'you are now inside ',$whoiam;
    my$HOMEarg={@_};
    my $subref=\&{ $HOMEarg->{subname} };
    say $subref;
    #my $reftostore=\&{ $HOMEarg->{subname} }->(); # generates error
    my $reftostore=$subref->();
    my$path=abs_path('.') . '/' . $HOMEarg->{subname} . '.perlstorable' ;
    store($reftostore,$path);
    say 'we have stored to ',$path;
}

sub writeeverythingtwice
{
    use Cwd 'abs_path'; use Storable;
    # https://stackoverflow.com/questions/30236740/generating-a-subroutine-reference-from-a-string
    my$whoiam= (caller(0))[3]; say 'you are now inside ',$whoiam;
    my$HOMEarg={@_};
    my$path=abs_path('.') . '/' . $HOMEarg->{name} . '.perlstorable' ;
    my$reftostore=$HOMEarg->{ref}->();
    store($reftostore,$path);
    say 'we have stored to ',$path;
}

sub doggy
{
    my$whoiam= (caller(0))[3]; say 'you are now inside ',$whoiam;
    return [ 'foo','bar' ];
}




Answered By - Jacob Wegelin
Answer Checked By - Robin (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing