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

    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. 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
    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 Morrow, Aug 11, 2008
  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';


    $lb_lang = 'en' unless defined $lb_lang;

    Michael Carman, Aug 11, 2008
  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
  6. Or just

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

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

    Search pattern not terminated at ./foo line 6.

    Peter J. Holzer, Aug 11, 2008
  8. Lars Eighner

    Matt Guest

    Thanks for catching that "defined" thing Michael.
    Matt, Aug 11, 2008
  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:
    osname=freebsd, osvers=7.0-stable, archname=i386-freebsd-64int
    uname='freebsd 7.0-stable freebsd \
    7.0-stable #0: mon apr 21 11:15:06 cdt 2008 \ 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 \
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=undef uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
    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
  10. Here's my test program:

    use warnings;
    use strict;

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

    Peter J. Holzer, Aug 11, 2008
  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
  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 //


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

    Ben Morrow Guest

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

    Ben Morrow, Aug 11, 2008
  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
  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.

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

    Peter J. Holzer, Aug 12, 2008
  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.

    Peter J. Holzer, Aug 12, 2008
  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"}
    Useless use of anonymous hash ({}) in void context at -e line 1.
    Odd number of elements in anonymous hash at -e line 1.
    Hm, with 5.8.8, I see a different yell:

    # /opt/perl-5.8.8/bin/perl -w
    $lb_lang // $lb_lang = "en"
    Search pattern not terminated at - line 1
    comp.lang.c++, Aug 14, 2008
    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.