double slash operator syntax question

L

Lars Eighner

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.
 
M

Matt

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.
 
B

Ben Morrow

Quoth Lars Eighner said:
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'};

$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.

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...)
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.

Yes, exactly.

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

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

Ben
 
M

Michael Carman

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

It's the defined-or operator that was added in Perl 5.10. It's like ||
but tests for definedness instead of truth.
$lb_lang = $lb_lang ? $lb_lang : "en";
$lb_lang = $lb_lang || "en";

I think either of those should work.

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
 
L

Lars Eighner

In our last episode,
the lovely and talented Michael Carman
broadcast on comp.lang.perl.misc:
It's the defined-or operator that was added in Perl 5.10. It's like ||
but tests for definedness instead of truth.

It's in 5.8.8 or my perl is lying.
 
P

Peter J. Holzer

Quoth Lars Eighner said:
What I want to do: if $lb_lang is undefined, I want to set it.

What I wrote:

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

$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.

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. [...]
since you don't need to build a useless data structure,

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

Or just

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

hp
 
P

Peter J. Holzer

Michael Carman:


It's in 5.8.8 or my perl is lying.
I think your perl is lying. My perl 5.8.8 complains:

Search pattern not terminated at ./foo line 6.

hp
 
M

Matt

I think your perl is lying. My perl 5.8.8 complains:

    Search pattern not terminated at ./foo line 6.

        hp

Thanks for catching that "defined" thing Michael.
 
L

Lars Eighner

the said:
I think your perl is lying. My perl 5.8.8 complains:
Search pattern not terminated at ./foo line 6.

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 \
[email protected]: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
 
P

Peter J. Holzer

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:

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
 
L

Lars Eighner

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__

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.
 
J

Justin C

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:

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__

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!
 
B

Ben Morrow

Quoth Lars Eighner said:
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 \
[email protected]:usrobjusrsrcsysapr08 i386 '

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

Ben
 
L

Lars Eighner

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

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

Apparently the perl58 port does. the perl5 port is 5.6
 
M

Michael Carman

Peter said:
$lb_lang // ($lb_lang = 'en');

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
 
P

Peter J. Holzer

In our last episode, <[email protected]>, the
lovely and talented Peter J. Holzer broadcast on comp.lang.perl.misc:
Michael Carman:
It's the defined-or operator that was added in Perl 5.10. It's like ||
but tests for definedness instead of truth.

It's in 5.8.8 or my perl is lying.

I think your perl is lying. My perl 5.8.8 complains:

Search pattern not terminated at ./foo line 6.
[...]

Here's my test program: [...]
$lb_lang // ($lb_lang = 'en');

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

The difference is that {} doesn't do what the OP wanted, but () does.

hp
 
P

Peter J. Holzer

For some reason I find that very jarring.

So do I. But it was the minimal change which made the OP's
"$lb_lang // {$lb_lang = 'en'};" work.
I think it's because I prefer to use the low-precedence equivalents
when doing control flow.

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;
$lb_lang //= 'en';

is much cleaner, IMHO.

Yes. That's how I would write it.

hp
 
C

comp.lang.c++

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 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
If I omit the braces, it dies with:
Can't modify defined or (//) at etc.

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
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top