Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

What am I not understanding about $,

by Anonymous Monk
on May 01, 2016 at 05:55 UTC ( #1161974=perlquestion: print w/replies, xml ) Need Help??

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

Easy way around this, but I want to understand why it is not working as I expect.
#!/usr/bin/perl -w use strict; my @array = ( 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz ' ); print "@array[2,4]\n";
ghi mno
I want to get rid of the space, so I added:
local $, = undef;
But there is still a space in the output. Why? And is there some clever way of getting rid of the space without the obvious method of combining the two elements in a temporary variable and printing that?

Replies are listed 'Best First'.
Re: What am I not understanding about $,
by Athanasius (Archbishop) on May 01, 2016 at 06:17 UTC

    Actually, in this case the space is being added, not by the output field separator ($,), but by the list separator ($"), because the array slice is stringified. To get what you want, you can either (1) set $" to the empty string (not undef, that gives a warning), or (2) not stringify the array slice in the print statement:

    16:14 >perl -wE "my @array = qw(abc def ghi jkl mno); print @array[2,4 +], qq{\n};" ghimno 16:14 >

    See the entries for $" and $, in perlvar.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: What am I not understanding about $,
by Marshall (Canon) on May 01, 2016 at 06:58 UTC
    do not quote the array elements:
    print "@array[2,4]\n";
    #!/usr/bin/perl -w use strict; my @array = ( 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz ' ); print @array[2,4],"\n"; __END__ prints: ghimno
Re: What am I not understanding about $,
by Ovid (Cardinal) on May 03, 2016 at 17:32 UTC

    As pointed out, you probably want $" instead of $,, but in reality, you want to join those elements and print them that way:

    my @array = ( 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz ' ); my $output = join '', @array[2,4]; print "$output\n";

    Why is that better? Because nobody knows what $" is, but everyone knows what join() is. Always write your software to be as readable as possible :)

      Because nobody knows what $" is

      Anyone who doesn't know what $" is, almost certainly won't understand @array[2,4], so you better make that:

      my $output = join '', $array[2], $array[4];

      But then, even if they know about the function join(), they probably won't understand the statement join, so you'd better make that:

      my $output = join( '', $array[2], $array[4] );

      Then, of course, for consistency you should make that last line:

      print( "$output\n" );

      But WFT!? Variable names inside quoted strings? That can't be right:

      print( $output . "\n" );

      But what the hell is that dot doing there!?

      print( join( '', $output, "\n" ) );

      But hang on a minute! Nested function calls!? We can sort that abomination out:

      my $output2 = join( '', $output, "\n" ); print( $output2 );
      my @array = ( 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz ' ); my $output = join( '', $array[2], $array[4] ); my $output2 = join( '', $output, "\n" ); print( $output2 );

      But, but, but, where are the classes and objects and methods and, and and ... Sod this! I'm going back to a proper language like JavaPy++ Cscript 3000 where fings are dun proply!

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.

        The issue I have isn't so much with the core Perl behavior, so much as the plethora of built-in global variables in Perl, and the general abuse of globals. For example, in one of my @INC directories I ran ack '^\s*\$\w+::.*=' and read plenty of CPAN modules who set global variables for other packages and don't localize those changes. I've had my code break as a result of other people doing that and it's very hard to track down these bugs.

        When you combine the potential for mysterious action at a distance along with the relatively inscrutable punctuation variables, it's a double-whammy in my book. Thus, I used to use local $" = ...;, but I've stopped doing that and recommend join (yes, even with array slices) because it's clear and there's less risk of mysterious side effects.

        Ovid's reference to readability is wrong IMHO, the intent of "@array" is indeed clear.

        That's unfortunate because it transformed a perfectly sensible suggestion about robustness - try to avoid global variables if you can, they might bite you in the long run - in a battle for idioms.

        Some of your suggestions might be read in that light too, but I'd make them more explicit:

        • Variable names inside quoted strings? - are you thinking about overloading the stringification operator?
        • But what the hell is that dot doing there!? - are you thinking about overloading the dot operator?
        • ... I fail to see a reason why nested function calls might be detrimental from a robustness point of view though.

        Operator overloading is definitely possible but highly improbable though as it's quite difficult (at least for me) to overload an operator in every possible scope. I'm eager to see comments about it, I'll be able to learn something about operator overloading at last :).

        Anyway... I tend to consider operators safe and the transformations unneeded. (I would stress I in the last statement).

        Personally, I always feel a strange tingling when using "@expand_me", and I do so only in very basic situations and temporary print statements for debugging. I prefer Ovid's way in code that has a longer lifespan. This is where I set the line between idiomatic and idiotic (couldn't resist the pun, sorry).

        perl -ple'$_=reverse' <<<ti.xittelop@oivalf

        Io ho capito... ma tu che hai detto?

        Thank you oh so very much for reminding me why I left Perl Monks. I was last here 5 years ago under a name I have long since forgotten the password to, and to be honest who I am (or was) is of no consequence. If you need to know who I am to take me seriously, then you've already lost the plot.

        Do you remember the "fun" that was this SoPW? I was around for that and wondered why Abigail responded the way he did. Over time I came to understand his position; eventually leading me to quietly walk away a few years after the aforementioned exchange.

        I will leave you with two things:

        1. Mutating global state is bad. We all know this. Why should Perl special variables get a pass on that?
        2. And the last is certainly not the least.

      I so want to downvote this. Please stop trying to convert Perl into Java.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1161974]
Approved by Athanasius
Front-paged by davies
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (1)
As of 2023-03-25 00:27 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (62 votes). Check out past polls.