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

hai all

I have error message regarding about Amazon SES ,

Backslash found where operator expected at ./ses-get-stats.pl line 171 +, near "SES::call_ses \" (Do you need to predeclare SES::call_ses?) syntax error at ./ses-get-stats.pl line 171, near "SES::call_ses \" Global symbol "$response_code" requires explicit package name at ./ses +-get-stats.pl line 172. Global symbol "$response_content" requires explicit package name at ./ +ses-get-stats.pl line 174. Execution of ./ses-get-stats.pl aborted due to compilation errors.</p>
The script is

parse_args; validate_opts; prepare_params; my ($response_code, $response_content) = SES::call_ses \%params, \%opt +s; switch ($response_code) { case '200' { # OK print_response $response_content; exit 0; } case '400' { exit 1; } # BAD_INPUT case '403' { exit 31; } # SERVICE_ACCESS_ERROR case '500' { exit 32; } # SERVICE_EXECUTION_ERROR case '503' { exit 30; } # SERVICE_ERROR else { exit -1; } }
can someone told me what should I do with this backslash \%params and \%opts;

Replies are listed 'Best First'.
Re: backslash found where operator expected at
by ikegami (Pope) on Apr 21, 2021 at 21:23 UTC

    Don't use Switch! Nonsense errors like this is why.

    Replace

    switch ($response_code) { case '200' { # OK print_response $response_content; exit 0; } case '400' { exit 1; } # BAD_INPUT case '403' { exit 31; } # SERVICE_ACCESS_ERROR case '500' { exit 32; } # SERVICE_EXECUTION_ERROR case '503' { exit 30; } # SERVICE_ERROR else { exit -1; } }
    with, for example,
    for ($response_code) { if ($_ == 200) { # OK print_response $response_content; exit 0; }; $_ == 400 and exit 1; # BAD_INPUT $_ == 403 and exit 31; # SERVICE_ACCESS_ERROR $_ == 500 and exit 32; # SERVICE_EXECUTION_ERROR $_ == 503 and exit 30; # SERVICE_ERROR exit 255; }

    Note that I replaced exit(-1) with exit(255) since -1 isn't a valid exit code (at least not on Windows, Linux and macOS).

    Seeking work! You can reach me at ikegami@adaelis.com

      In the spirit of TIMTOWTDI:
      my $handles = { 400 => 1, # BAD_INPUT 403 => 31, # SERVICE_ACCESS_ERROR 500 => 32, # SERVICE_EXECUTION_ERROR 503 => 30, # SERVICE_ERROR }; for ($response_code) { if ($_ == 200) { # OK print_response $response_content; exit 0; }; if (defined $handles->{$_}) { exit $handles->{$_}; } }
      $handles could also be a CODE refs that do something, then exit:
      my $handles = { 200 => sub { print_response $response_content; 0}, # OK! 400 => sub { 1}, # BAD_INPUT 403 => sub {31}, # SERVICE_ACCESS +_ERROR 500 => sub {32}, # SERVICE_EXECUT +ION_ERROR 503 => sub {30}, # SERVICE_ERROR }; for ($response_code) { if (defined $handles->{$_}) { # check for 'CODE' ref up to you exit $handles->{$_}->(); } }

        I love dispatch tables. Definitely something to consider in such situations. I simply didn't think them particularly clear/clean/useful here.

        Seeking work! You can reach me at ikegami@adaelis.com

Re: backslash found where operator expected at
by GrandFather (Saint) on Apr 21, 2021 at 21:12 UTC
    use strict; use warnings; use Switch; package SES; sub call_ses { my ($paramHash, $optHash) = @_; print "$_ $paramHash->{$_}\n" for keys %$paramHash; return 400, ''; } package main; my %params = (hello => "world"); my %opts; my ($response_code, $response_content) = SES::call_ses \%params, \%opt +s; switch() { case '400' {} }

    prints:

    hello world

    as expected so there is more going on than you are showing. Maybe you should generate the sensible minimum code required to reproduce the issue? See I know what I mean. Why don't you? for some hints.

    Note that use of the Switch module is strongly discouraged and has been for a long time. Not the smoking gun in this case, but best practice would avoid using it.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
      Sorry for hijacking the thread, my issue is on the SES::call_ses side. If I shift $self I get an error about an empty hash for %$opts, if I don't shift $self it works. This works:
      sub call_ses { my $params = shift; my $opts = shift; %opts = %$opts; %params = %$params; my $endpoint_name = $endpoint; }
      This doesn't:
      sub call_ses { my $self = shift; my $params = shift; my $opts = shift; %opts = %$opts; <-- Line 559 %params = %$params; my $endpoint_name = $self->AWS_endpoint; }
      Can't use an undefined value as a HASH reference at /usr/share/perl5/vendor_perl/SES.pm line 559 (#1) (F) A value used as either a hard reference or a symbolic referenc +e must be a defined value. This helps to delurk some insidious errors. Uncaught exception from user code: Can't use an undefined value as a HASH reference at /usr/share +/perl5/vendor_perl/SES.pm line 559. SES::call_ses('HASH(0x243cc00)', 'HASH(0x26a2138)') called at +/opt/aws/apitools/ses/bin/ses-get-stats.pl line 168
      Should I abandon $self and just call the subs like I did in the working version? Thanks to the Monastery for all the years of saving my butt as I stumbled through PERL.

        $self as the first parameter of a subroutine is required if - and only if - the subroutine is called as an object or class method, and the name "self" is just a convention for the object or class the method operates on. You did not provide the code how you're calling call_ses and the only reference I found for your module is that aws-apitools have been deprecated as of 2015. Perhaps you might want to have a look for CPAN modules which provide an interface to SES, like e.g. Net::AWS::SES or Paws::SES?

        Further to haj's reply ...

        According to the code examples posted so far in this thread, SES::call_ses does not appear to be a method of the SES class, so assigning to a $self variable, which is, by convention, usually used to denote an object reference to or the class name of a class method, makes no sense.

        In the invocation
            my ($response_code, $response_content) = SES::call_ses \%params, \%opts;
        \%params is not a bless-ed reference (i.e., an object reference) of any kind, so don't treat it as such in a call to $self->AWS_endpoint in the

        sub call_ses { my $self = shift; ... my $endpoint_name = $self->AWS_endpoint; }
        function.

        SES::call_ses seems to be an ordinary subroutine defined in the SES package. This subroutine does not seem to be exported, so it must be invoked via the fully-qualified SES::call_ses syntax. According to the error message, this subroutine was called with two arguments, so shifting three arguments off of the @_ argument array will leave someone holding an undefined bag. Don't do that.


        Give a man a fish:  <%-{-{-{-<

        Thanks to the Monastery for all the years of saving my butt

        Welcome back, jmccall! ;-)

Re: backslash found where operator expected at
by BillKSmith (Prior) on Apr 22, 2021 at 15:38 UTC
    I like to use the Ternaries as suggested in the book "Perl Best Practices".
    use strict; use warnings; sub print_response; my $response_code = 200; my $response_content = "All's well!"; use constant OK => 0; use constant BAD_INPUT => 1; use constant SERVICE_ACCESS_ERROR => 31; use constant SERVICE_EXECUTION_ERROR => 32; use constant SERVICE_ERROR => 30; use constant UNDEFINED => 255; $_ = $response_code; my $return_status = /200/ ? OK : /400/ ? BAD_INPUT : /403/ ? SERVICE_ACCESS_ERROR : /500/ ? SERVICE_EXECUTION_ERROR : /503/ ? SERVICE_ERROR : UNDEFINED ; print_response $response_content if $return_status == OK; exit $return_status;

    The constants may be overkill, but if the names are important enough to include as comments, why not make them part of the actual perl code?

    UPDATE -- Corrected sense of if statement

    Bill
Re: backslash found where operator expected at
by Discipulus (Abbot) on Apr 21, 2021 at 20:58 UTC
    Hi tokodekat and welcome to the monastery and to the wonderful world of perl!

    SES::call_ses (\%params, \%opts) compiles better?

    perl error reporting is generally really helpful and worth to read carefully: ..at ./ses-get-stats.pl line 171, near "SES::call_ses \

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      yes .it work with (\%params, \%opts) thankyou ,