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

sub myrun{ ...} my $run = $condition ? 'system' : 'myrun';

$run @args; or eval {$run @args} did not work like bash do

what's the trick perl use about this?

Replies are listed 'Best First'.
Re: how to assign 'system' to a value, and eval it.
by hippo (Archbishop) on Jun 09, 2024 at 16:33 UTC

    Sounds like a job for coderefs.

    #!/usr/bin/env perl use strict; use warnings; sub myrun { print "Yeah, just printing @_\n"; } sub mysystem { system @_; } for (0..6) { my $run = $_ % 2 ? \&mysystem : \&myrun; $run->("echo Number $_"); }
    did not work like bash do

    You'll have to give more detail here. An SSCCE would be good.


    🦛

      And the google fodder you're (the OP) probably going to want next is "dispatch table".

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

      yeah, thank you.that's the way I want.now I realized the necessity of using reffed subroutine.
      my %run = (x => \&system, X => \&myrun); my ($run, @args); foreach(@ARGV){ if (/^-([xX])$/){ $run = $run{$1} }elsif (/^-/){ push @args, $_ } $run->(@args)
      It's using prepared hash to switch run command, that's the logical way instead of using 'if ($run eq 'x'){system ...}', the ugly way I tried to avoid.

        Consider using Getopt::Long instead of hand-rolling your option parsing. Getopt::Long can also set up your callbacks but will handle many more features:

        use Getopt::Long qw(:config pass_through); my $run; GetOptions( 'x|run-using-system' => sub { $run = \&system }, 'X|run-using-mysystem' => sub { $run = \&mysystem }, ); $run->(@ARGV);
Re: how to assign 'system' to a value, and eval it.
by soonix (Chancellor) on Jun 09, 2024 at 15:52 UTC
    consider the difference between
    'system'($whatever); 'myrun'($whatever);
    and
    system($whatever); myrun($whatever);
    • $system is a variable (as you know)
    • system is a function
    • 'system' is a string
      yeah, perl did not try to '$command xxx' like bash do. that's a good behavior.
Re: how to assign 'system' to a value, and eval it.
by harangzsolt33 (Deacon) on Jun 09, 2024 at 21:02 UTC
    Personally, I would avoid using eval, but if you're going to use eval, you might as well do it this way:

    #!/usr/bin/perl -w use strict; use warnings; my $condition = 0; sub RunProg # Run program only if it exists { my $CMD = join(' ', @_); my $PRG = ($CMD =~ m/^([a-zA-Z0-9_\/\-.~!]+)/) ? $1 : ''; if (length(`which $PRG`)) { return system("$CMD"); } return -1; } my @args = ('yad --help'); my $RET = eval(($condition ? 'system' : 'RunProg') . '(@args);' ); print "\nRETURN VALUE = $RET\n";
        if (length(`which $PRG`))

      Use the core module IPC::Cmd for increased portability and functionality:

      use IPC::Cmd 'can_run'; my $path = can_run($PRG);
        I don't know IPC has it.
      That helps too.