double slash operator syntax question

Discussion in 'Perl Misc' started by Lars Eighner, Aug 11, 2008.

  1. Lars Eighner

    Lars Eighner Guest

    I may have asked this in another form recently, but I'm senile, so indulge
    me.

    What I want to do: if $lb_lang is undefined, I want to set it.

    What I wrote:

    $lb_lang // {$lb_lang = 'en'};

    What perl -w yelled:

    Useless use of single ref constructor in void context at etc.
    But it seems to work in spite of the yelling.

    If I omit the braces, it dies with:
    Can't modify defined or (//) at etc.


    My understanding of what // is supposed to be: It is like
    || but tests the left side for definedness instead of for value,
    so this should be like a || command list.
     
    Lars Eighner, Aug 11, 2008
    #1
    1. Advertisements

  2. Lars Eighner

    Matt Guest

    I don't know about // being some kind of operator other than a pattern
    match operator...but you could accomplish that like this

    $lb_lang = $lb_lang ? $lb_lang : "en";
    or like this
    $lb_lang = $lb_lang || "en";

    I think either of those should work.
     
    Matt, Aug 11, 2008
    #2
    1. Advertisements

  3. Lars Eighner

    Ben Morrow Guest

    $lb_lang //= 'en';
    Well, sort-of. You are actually constructing an anon hashref out of the
    single-element list ('en') (and I'm slightly surprised -w didn't warn
    about that, as well), and assigning to $lb_lang as a side-effect. Using
    the array constructor

    $lb_lang // [$lb_lang = 'en'];

    would work just as well; or, since you don't need to build a useless
    data structure,

    $lb_lang // do { $lb_lang = 'en' };

    'do' makes the block into a block, rather than an anon hash.
    (Annoyingly, the 'err' operator which was the low-precedence form of //
    was removed just before 5.10.0. I never really understood why...)
    Yes, exactly.

    $lb_lang || {$lb_lang = 'en'};

    behaves exactly the same way (except for the test performed).

    Ben
     
    Ben Morrow, Aug 11, 2008
    #3
  4. It's the defined-or operator that was added in Perl 5.10. It's like ||
    but tests for definedness instead of truth.
    Not quite; those both test for boolean truth. The OP stated that he
    wanted to set the variable if it wasn't _defined_. The important
    difference is the behavior if the initial value of $lb_lang is defined
    but false (0, '0', or '')

    The typical ways of doing this prior to Perl 5.10 are:

    $lb_lang = defined($lb_lang) ? $lb_lang : 'en';

    or

    $lb_lang = 'en' unless defined $lb_lang;

    -mjc
     
    Michael Carman, Aug 11, 2008
    #4
  5. Lars Eighner

    Lars Eighner Guest

    In our last episode,
    the lovely and talented Michael Carman
    broadcast on comp.lang.perl.misc:
    It's in 5.8.8 or my perl is lying.
     
    Lars Eighner, Aug 11, 2008
    #5
  6. Or just

    $lb_lang // ($lb_lang = 'en');

    hp
     
    Peter J. Holzer, Aug 11, 2008
    #6
  7. I think your perl is lying. My perl 5.8.8 complains:

    Search pattern not terminated at ./foo line 6.

    hp
     
    Peter J. Holzer, Aug 11, 2008
    #7
  8. Lars Eighner

    Matt Guest

    Thanks for catching that "defined" thing Michael.
     
    Matt, Aug 11, 2008
    #8
  9. Lars Eighner

    Lars Eighner Guest

    Curious. As I said, it works on mine, and perl -V has this
    to say for itself:

    Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
    Platform:
    osname=freebsd, osvers=7.0-stable, archname=i386-freebsd-64int
    uname='freebsd debranded.6dollardialup.com 7.0-stable freebsd \
    7.0-stable #0: mon apr 21 11:15:06 cdt 2008 \
    toor@debranded.6dollardialup.com:usrobjusrsrcsysapr08 i386 '
    config_args='-sde -Dprefix=/usr/local \
    -Darchlib=/usr/local/lib/perl5/5.8.8/mach \
    -Dprivlib=/usr/local/lib/perl5/5.8.8 \
    -Dman3dir=/usr/local/lib/perl5/5.8.8/perl/man/man3 \
    -Dman1dir=/usr/local/man/man1 \
    -Dsitearch=/usr/local/lib/perl5/site_perl/5.8.8/mach \
    -Dsitelib=/usr/local/lib/perl5/site_perl/5.8.8 \
    -Dscriptdir=/usr/local/bin \
    -Dsiteman3dir=/usr/local/lib/perl5/5.8.8/man/man3 \
    -Dsiteman1dir=/usr/local/man/man1 \
    -Ui_malloc -Ui_iconv -Uinstallusrbinperl \
    -Dcc=cc -Duseshrplib \
    -Dccflags=-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" \
    -Doptimize=-O2 -fno-strict-aliasing -pipe -Ud_dosuid -Ui_gdbm \
    -Dusethreads=n -Dusemymalloc=y -Duse64bitint'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef \
    usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=undef uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
    Compiler:
    cc='cc', ccflags ='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" \
    -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe \
    -Wdeclaration-after-statement -I/usr/local/include',
    optimize='-O2 -fno-strict-aliasing -pipe ',
    cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" \
    -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe \
    -Wdeclaration-after-statement -I/usr/local/include'
    ccversion='', gccversion='4.2.1 20070719 [FreeBSD]', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='double', \
    nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
    Linker and Libraries:
    ld='cc', ldflags =' -Wl,-E
     
    Lars Eighner, Aug 11, 2008
    #9
  10. Here's my test program:

    #!/usr/bin/perl
    use warnings;
    use strict;

    my $lb_lang = $ARGV[0];
    $lb_lang // ($lb_lang = 'en');
    print "$lb_lang\n"
    __END__

    hp
     
    Peter J. Holzer, Aug 11, 2008
    #10
  11. Lars Eighner

    Lars Eighner Guest

    runs perfectly (because there is a link to the real location of perl
    in freeBSD)

    The source my perl was compiled from is perl-5.8.8.tar.bz2 . I don't
    even have source for 5.10.x on my machine.

    I don't get it.
     
    Lars Eighner, Aug 11, 2008
    #11
  12. Lars Eighner

    Justin C Guest

    Just an observation, I don't know if it makes a difference[1], the OP had
    {} and not () after the //

    Justin.


    1. That's why I'm here, 'cos I don't know!
     
    Justin C, Aug 11, 2008
    #12
  13. Lars Eighner

    Ben Morrow Guest

    This is the perl from ports, yes? ports perl applies the dor patch by
    default.

    Ben
     
    Ben Morrow, Aug 11, 2008
    #13
  14. Lars Eighner

    Lars Eighner Guest

    In our last episode, <>, the lovely
    and talented Ben Morrow broadcast on comp.lang.perl.misc:

    Apparently the perl58 port does. the perl5 port is 5.6
     
    Lars Eighner, Aug 11, 2008
    #14
  15. For some reason I find that very jarring. I think it's because I prefer
    to use the low-precedence equivalents when doing control flow. (Of
    course, // doesn't have one.)

    $lb_lang //= 'en';

    is much cleaner, IMHO.

    -mjc
     
    Michael Carman, Aug 12, 2008
    #15
  16. The difference is that {} doesn't do what the OP wanted, but () does.

    hp
     
    Peter J. Holzer, Aug 12, 2008
    #16
  17. So do I. But it was the minimal change which made the OP's
    "$lb_lang // {$lb_lang = 'en'};" work.
    I prefer those, too (maybe just because they save some parentheses), but
    in this case I think the aesthetical problem are

    * $lb_lang is mentioed twice without need:
    $lb_lang //= 'en';
    does what we want and is shorter and clearer
    * A logical operator is used only for control flow: Before 5.10 I
    wouldn't write that as
    defined $lb_lang or $lb_lang = 'en'
    but as
    $lb_lang = 'en' unless defined $lb_lang;
    Yes. That's how I would write it.

    hp
     
    Peter J. Holzer, Aug 12, 2008
    #17
  18. If you're able to upgrade, you'll get even more
    yelling :)

    # /opt/perl-5.10.0/bin/perl -w
    $lb_lang // {$lb_lang = "en"}
    ^D
    Useless use of anonymous hash ({}) in void context at -e line 1.
    Odd number of elements in anonymous hash at -e line 1.
    en
    Hm, with 5.8.8, I see a different yell:

    # /opt/perl-5.8.8/bin/perl -w
    $lb_lang // $lb_lang = "en"
    ^D
    Search pattern not terminated at - line 1
     
    comp.lang.c++, Aug 14, 2008
    #18
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.