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

Hi Monks,
I have a question regarding map.

I have a variable $param = '196', 'berg',NULL,NULL;
I want to split this and also remove the single qoutes around the number and also make the NULL value undef. So I wrote this split and map functions together

my @list_of_params = map { s/^\'(.*?)\'$/$1/m } map { $_ eq 'NULL' ? undef : $_ } split(/\s*\,\s*/,$params);
I am getting a value of 1 in @list_of_params. Can any of the monks help me out.

Thanks

Code tags and general htmlification- dvergin 2003-09-10

Replies are listed 'Best First'.
Re: map not returning
by BrowserUk (Patriarch) on Sep 11, 2003 at 02:02 UTC

    You have several problems.

    • You are converting your 'NULL' strings to undefs before you do the substitutions to remove the quotes.

      If you had warnings enabled you would see that this causes two "Use of uninitialized value in substitution (s///) at ..." messages. One for each of the undefs.

      A simple solution to this is to reverse the order of your maps.

    • Your substitution map is returning the result of the substitution hence the two 1s. One for each of the two values that are matched '196' and 'berg'.

      The simple answer here is to make sure that the result of the map (the last value in the code block) is $_.

    • According to your text, you only want to strip 's around the number, but your substitution is also stripping them from 'berg'.

      This may just be words, but if you really only want to strip them from the number(s) then you should change thematch in the substitution to s/^\'(\d+?)\'$/....

    Your also backwacking more than is necessary. Putting that all together we get

    my $params = "'196', 'berg',NULL,NULL"; my @list_of_params = map { $_ eq 'NULL' ? undef : $_ } map { s/^'(\d+?)'$/$1/m; $_ } split /\s*,\s*/, $params ;

    It's probably not the way I would have done it, but it does correct some errors and produce the output you want.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

      You don't really need two maps, just put both statements in one map:
      my $params = "'196', 'berg',NULL,NULL"; my @list_of_params = map { s/^'(\d+?)'$/$1/m; $_ eq 'NULL' ? undef : $_ } split /\s*,\s*/, $params;
Re: map not returning
by davido (Cardinal) on Sep 11, 2003 at 00:29 UTC
    If I understand your question.....

    $param =~ s/'(\d+)'/$1/g; $param =~ s/NULL/undef/g; @list_of_params = split /\s*,\s*/, $param;

    Map would be useful if you were already dealing with a list. No point splitting things into a list before you've taken advantage regular expressions to substitute where necessary.

    UPDATE: Thanks BrowserUK for the little tip. So as to actually substitute NULL with the undef value (rather than the 'undef' string), I propose this:

    $param =~ s/'(\d+)'/$1/g; @list_of_params = map { ($_ eq 'NULL') ? undef : $_ } split( /\s*,\s*/, $param );

    Yes, it can be done in a one-liner using two map calls, but I still think that's making it a little too complex (and difficult to maintain in the future).

    Dave

    "If I had my life to do over again, I'd be a plumber." -- Albert Einstein

      Your replacing the word NULL with the word "undef" rather than the value undef which the OP was doing.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

Re: map not returning
by Anonymous Monk on Sep 11, 2003 at 00:34 UTC
    Without much modification of your code:
    my $params = q('196','berg',NULL,NULL); my @list_of_params = map { s/^\'(.*?)\'$/$1/m; $_} map { $_ eq 'NULL' ? 'undef' : $_ } split(/\s*\,\s*/,$params);

    artist
    ========

      While that's a great use of map if you're trying to win an obfu contest, that method is too aggressive at removing single quotes. He specified that he wanted to remove single quotes from the number, not from the word 'berg'.

      It would work better like this:

      my @list_of_params = map { s/^'(\d+?)'$/$1/ } map { $_ eq 'NULL' ? 'undef' : $_ } split (/\s*,\s*/,$params);

      Dave

      "If I had my life to do over again, I'd be a plumber." -- Albert Einstein

        Thanks I got it fixed.