in reply to Using s/// Inline

($key=~m{^\d+$} ? "fid" : "name") => ($key=~m{^\d+$} ? $key : lc($key =~ s/[^a-z0-9]/_/ig))

Do you think that's readable? And you want to add to it? Whoa!

sub add_record { my ($self, $data) = @_; my @record; for my $key (keys %$data) { my $att_key = $key =~ /[^0-9]/ ? "name" : "fid"; ( my $att_val = lc($key) ) =~ s/[^a-z0-9]/_/g; push @record, { tag => "field", atts => { $att_key => $att_val }, value => $data->{$key}, }; } return post_api("API_AddRecord", \@record); }

By the way, don't use prototypes! You didn't even use the right one, so that means you have to bypass it to call your sub!

Replies are listed 'Best First'.
Re^2: Using s/// Inline
by bichonfrise74 (Vicar) on Nov 16, 2009 at 19:39 UTC
    Hi Ikegami,

    I was looking at the search result of prototypes in perlmonk and found that the general wisdom is not to use prototypes. But is there a good explanation as to why it should not be used?

    I looked at Prototypes and it looks like prototypes are useful if you want to control the arguments coming into your subroutine (this might be wrong, but this is just how I understood).

      Simply put, they change the parsing rules (e.g. the evaluation context of the arguments). Did you mean to change the parsing rules? No, you probably wanted some form of argument validation. Therefore, you shouldn't be using prototypes.

      Besides, you were placing them on methods where they are totally ignored (to the point that you were using the wrong one and you didn't notice).

        @ikegami, I believe you've mistaken bichonfrise74 and myself as being the same person, however it seems they've simply stumbled across this thread and wanted some clarification on how perl's prototypes work.

        I would like to note, though, that I made some hasty last-minute changes to that subroutine before posting in an attempt to trim it down to only the code that I felt was relevant to the issue at hand. Unfortunately I neglected to remove the $self initialization at the top of the subroutine, which seems to have caused some confusion.

        @bichonfrise74, I'm rather new to perl, myself, but I did some digging and it seems that the prototypes don't necessarily enforce constraints on subroutine arguments, rather they coerce the arguments that are passed into the variable types listed in the prototype. At least, that's the impression I got from http://www.perlfoundation.org/perl5/index.cgi?prototype

        Update: Seems I was a little hasty in my interpretation. "Coerced" isn't necessarily the correct word there, as it implies the variable's value would remain yet be offered in a new context. Instead, the arguments are interpreted by the subroutine as being in the context of the prototype, meaning if an @array is passed where a $scalar is expected, what would result is actually the length of that array, since $scalar = @array assigns the length of @array to @scalar.

        I hope that's clearer, my apologies for any misunderstandings.

Re^2: Using s/// Inline
by Jason Hutchinson (Acolyte) on Nov 16, 2009 at 16:41 UTC

    Many thanks, ikegami. The modified version in your reply is much more readable and functions exactly as I need it to.

    I have also taken your advice against prototypes and removed them from the SDK. I have to admit that I didn't see any benefit to them, and was only keeping them in the module because the original creator had them there.