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

Why, why, why does this not do what I think it should?
#!/usr/local/bin/perl print join(/:/,"dog","day","afternoon"); print "\n"; ./joinit dogdayafternoon

20040915 Edit by castaway: Changed title from 'join'

Replies are listed 'Best First'.
Re: join doesn't seem to insert separators
by zdog (Priest) on Sep 13, 2004 at 23:18 UTC

    Try this:

    print join( ":", "dog", "day", "afternoon" );

    The first argument join() takes is the expression with which you want to connect the list. In this case, you want to pass a string rather than a regular expression (or whatever /:/ turns out to be).

    Zenon Zabinski | zdog | zdog@perlmonk.org

Re: join doesn't seem to insert separators
by sintadil (Pilgrim) on Sep 13, 2004 at 23:26 UTC

    print join(/:/,"dog","day","afternoon");

    What zdog didn't mention is that join() doesn't take a regular expression as its first argument like split() does. Instead, it takes an expression that yields something that Perl can transform into a string.

Re: join doesn't seem to insert separators
by davido (Cardinal) on Sep 14, 2004 at 04:00 UTC

    Both of the previous responses you received were spot on, but I wanted to mention one other thing. As the other responses mentioned, the first argument of join is an argument that should evaluate to the string you wish to use in joining the list that follows. Normally that expression will be a quoted string. In the case of your need, that could be join ":", "dog", "day", "afternoon";, or you could use single quotes instead of double quotes. Both of those will evaluate to a string that pretty much looks like what you've put literally between the quote operators. But remember, any expression will do.

    The problem you're seeing is that in using a regexp type operator, when that operator is evaluated, it returns a boolean value: truth or falsehood, based on Perl's notion of true and false. Quotes are operators too. They just return a string equal to the literal text they enclose (interpolated in the case of double-quotes). If your expression were join 1, "dog", "day", "afternoon", the output would be "dog1day1afternoon".

    Now for the surprise. Try the following code and see what happens:

    $_ = ':'; print join /:/, "dog", "day", "afternoon";

    Now why on earth would the output here be "dog1day1afternoon"? Because m/:/ is implicitly matched against the contents of $_, which we've set to ":". So the result is ...a match: success, truth, and in fact, "1".

    Isn't that cool? ;)


    Dave

Re: join doesn't seem to insert separators
by tinita (Parson) on Sep 15, 2004 at 10:58 UTC
    easy:
    use warnings; would have spotted the error for you:
    /:/ should probably be written as ":" at -e line 3.

    always use warnings;