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

Why do in two lines what I can do in one, eh?

I have a string "string" with the value say "This is a string"
Now I want to split $string then grab something out of the result in a scheme-like car/cdr kinda way.

I tried the following:

my $first = shift ( split / /,$string );

but perl didn't like it.

Why not? I mean, split returns a list; a list can be interpreted as an array; pop expects an array. Seems logical to me?

Also, what perl commands are a good substitute for car/cdr from scheme? Sure shift is kinda like car, but it modifies the original list.

Anyway, thanks for any help
  • Comment on How can I use the the return value of split without assigning?

Replies are listed 'Best First'.
Re: How can I use the the return value of split without assigning?
by japhy (Canon) on Jul 27, 2001 at 01:30 UTC
    Just use list slices:
    my $first = (split /=/, $string)[0]; # or even... my ($first) = split /=/, $string;

    _____________________________________________________
    Jeff japhy Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: How can I use the the return value of split without assigning?
by ChemBoy (Priest) on Jul 27, 2001 at 01:36 UTC

    I think the problem is that when you use shift, you're trying to alter its argument, which you can't alter (I haven't tried that particular maneuver, but I imagine it's the same error I get from pop=~s/foo/bar/). The solution is pretty simple, though: treat the split return as a list (I believe this is one of those cases where the difference between a list and an array matters), which you can index things out of, like so:

    my $first = (split//,$string)[0];

    Note that if you want to use this as the first argument to a list operator (such as print), you need to do something to keep it from interpreting (split //, $string) as the arguments to the list operator (using the "if it looks like a function" rule), and complaining that you can't take an index out of print (can you tell I'm familiar with the error messages? ;-) :
    print +(split//,$string)[4];



    If God had meant us to fly, he would *never* have given us the railroads.
        --Michael Flanders

Re: How can I use the the return value of split without assigning?
by chromatic (Archbishop) on Aug 02, 2001 at 09:44 UTC
    I mean, split returns a list; a list can be interpreted as an array; pop expects an array. Seems logical to me?

    Yes, but backwards from the way the language works. Sorry, them's the breaks. This code doesn't work:

    1++;

    So I'll make a terrible analogy which someone like Dominus will have to correct, but maybe it'll help.

    A constant is not a scalar. A scalar can hold a constant. (told you it was bad). A list is not an array. An array can hold a list. You can use a scalar anywhere you can use a constant, but you can't use a constant anywhere you can use a scalar. You can use an array anywhere you can use a list, but you can't use a list anywhere you can use an array.

    One's read only, and the other's modifiable. That's why you can perform operations on scalars and arrays.

    Make sense?

Re: How can I use the the return value of split without assigning?
by no_slogan (Deacon) on Jul 27, 2001 at 01:54 UTC
    I don't think there's really a good reason from a language point of view why shift doesn't do what you want. It seems like an implementation issue. The interpreter could create a temporary array that can be modified by shift, but it just doesn't, because nobody thought it should. I'm not sure if I think it should or not.

    You can get the "car" (couldn't they have thought of a better name?) of an array like this:
    @x[1..$#x]
    But that's ugly and probably inefficient. And you have to actually assign your list to @x first, so you can't wedge it into the middle of an expression. Too bad you can't give an open-ended array slice, like this:
    (split / /, $string)[1..]

    Perl arrays are different from lisp lists. Some things that are easy with one may not be easy with the other. How could it be otherwise?

    Update: Did I get car and cdr mixed up again? I can't imagine how I could be so careless. Contents of address register, contents of decrement register - the difference couldn't be clearer!

      You can get the "car" (couldn't they have thought of a better name?)... Did I get car and cdr mixed up again?I can't imagine how I could be so careless.

      In Common Lisp, you may freely use 'first' instead of 'car' and 'rest' instead of 'cdr' - they're completely identical. I tend to use first/rest when I'm thinking of something as a list, and car/cdr when I'm thinking of it as a cons cell, but that's hardly a hard and fast rule, even for me.