Skip to content

Smart match doesn't work with list and given-when #10386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
p5pRT opened this issue May 18, 2010 · 9 comments
Closed

Smart match doesn't work with list and given-when #10386

p5pRT opened this issue May 18, 2010 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented May 18, 2010

Migrated from rt.perl.org#75152 (status was 'rejected')

Searchable as RT75152$

@p5pRT
Copy link
Author

p5pRT commented May 18, 2010

From [email protected]

Hello.

I tried to run the follow script, but I get wrong result.

I checked it, I think is correct.

Smarts matches in lines 12 and 16 doesn't work as expected. This piece of
code is part of a largest program, but this piece gives a wrong answer to me
(all numbers are odd!).

Hugs! Thanks by attention.

Case of test used​:


1 #!/usr/bin/perl
2
3 use 5.010;
4
5 print "Enter number​: ";
6 chomp($number = <STDIN>) while (!($number ~~ /^\s*(0|[1-9]+)\s*$/));
7
8 @​divisors = &getdivisors($number);
9
10 say "Divisors​: @​divisors";
11 given( $number ) {
12 when( @​divisors ~~ 2 ) {
13 say "$_ is a even number.";
14 continue;
15 }
16 when( !(@​divisors ~~ 2) ) {
17 say "$_ is a odd number.";
18 }
19 }
20
21 sub getdivisors {
22 my ($div, @​divisors) = (1);
23
24 while ($div <= $_[0]) {
25 push(@​divisors, $div) unless ($_[0] % $div);
26 ++$div;
27 }
28
29 return @​divisors;
30 }


Use of uninitialized value $category in concatenation (.) or string at
/usr/local/bin/perlbug line 645.
Use of uninitialized value $severity in concatenation (.) or string at
/usr/local/bin/perlbug line 645.


Flags​:
  category=?
  severity=high


Site configuration information for perl 5.12.0​:

Configured by eof at Tue May 11 08​:12​:38 BRT 2010.

Summary of my perl5 (revision 5 version 12 subversion 0) configuration​:

  Platform​:
  osname=linux, osvers=2.6.32-22-generic, archname=i686-linux
  uname='linux golden-eagle 2.6.32-22-generic #33-ubuntu smp wed apr 28
13​:27​:30 utc 2010 i686 gnulinux '
  config_args='-de'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=undef, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include'
  ccversion='', gccversion='4.4.3', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=define, longUse of uninitialized value $category in
concatenation (.) or string at /usr/local/bin/perlbug line 645.
Use of uninitialized value $severity in concatenation (.) or string at
/usr/local/bin/perlbug line 645.


Flags​:
  category=
  severity=high


Site configuration information for perl 5.12.0​:

Configured by eof at Tue May 11 08​:12​:38 BRT 2010.

Summary of my perl5 (revision 5 version 12 subversion 0) configuration​:

  Platform​:
  osname=linux, osvers=2.6.32-22-generic, archname=i686-linux
  uname='linux golden-eagle 2.6.32-22-generic #33-ubuntu smp wed apr 28
13​:27​:30 utc 2010 i686 gnulinux '
  config_args='-de'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=undef, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include'
  ccversion='', gccversion='4.4.3', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
  alignbytes=4, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /usr/lib64
  libs=-lnsl -ldl -lm -lcrypt -lutil -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=/lib/libc-2.11.1.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.11.1'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib
-fstack-protector'

Locally applied patches​:


@​INC for perl 5.12.0​:
  /usr/local/lib/perl5/site_perl/5.12.0/i686-linux
  /usr/local/lib/perl5/site_perl/5.12.0
  /usr/local/lib/perl5/5.12.0/i686-linux
  /usr/local/lib/perl5/5.12.0
  .


Environment for perl 5.12.0​:
  HOME=/home/eof
  LANG=en_US.utf8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)

PATH=/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/bashlongsize=8, d_longdbl=define, longdblsize=12
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
  alignbytes=4, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /usr/lib64
  libs=-lnsl -ldl -lm -lcrypt -lutil -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=/lib/libc-2.11.1.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.11.1'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib
-fstack-protector'

Locally applied patches​:


@​INC for perl 5.12.0​:
  /usr/local/lib/perl5/site_perl/5.12.0/i686-linux
  /usr/local/lib/perl5/site_perl/5.12.0
  /usr/local/lib/perl5/5.12.0/i686-linux
  /usr/local/lib/perl5/5.12.0
  .


Environment for perl 5.12.0​:
  HOME=/home/eof
  LANG=en_US.utf8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)

PATH=/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/bash

--
Hudson Flávio Vieira Mateus
7° período - Ciência da Computação
Universidade Federal de Lavras

Linux registered user #488195

@p5pRT
Copy link
Author

p5pRT commented May 18, 2010

From @rgarcia

2010/5/18 Hudson Flávio Vieira Mateus <perlbug-followup@​perl.org>​:

Hello.

I tried to run the follow script, but I get wrong result.

I checked it, I think is correct.

Smarts matches in lines 12 and 16 doesn't work as expected. This piece of
code is part of a largest program, but this piece gives a wrong answer to me
(all numbers are odd!).

Hugs! Thanks by attention.

Case of test used​:
----------------------------------------------
1  #!/usr/bin/perl
2
3  use 5.010;
4
5  print "Enter number​: ";
6  chomp($number = <STDIN>) while (!($number ~~ /^\s*(0|[1-9]+)\s*$/));
7
8  @​divisors = &getdivisors($number);
9
10 say "Divisors​: @​divisors";
11 given( $number ) {
12     when( @​divisors ~~ 2 ) {

You want if() there, not when(), because $number is not used in your condition.
Also, to test correctly, you should invert the operands :
if (2 ~~ @​divisors) ...
This is described in more detail in the perlsyn man page.

13         say "$_ is a even number.";
14         continue;
15     }
16     when( !(@​divisors ~~ 2) ) {
17         say "$_ is a odd number.";
18     }
19 }
20
21 sub getdivisors {
22     my ($div, @​divisors) = (1);
23
24     while ($div <= $_[0]) {
25         push(@​divisors, $div) unless ($_[0] % $div);
26         ++$div;
27     }
28
29    return @​divisors;
30 }
----------------------------------------------

Use of uninitialized value $category in concatenation (.) or string at
/usr/local/bin/perlbug line 645.
Use of uninitialized value $severity in concatenation (.) or string at
/usr/local/bin/perlbug line 645.
---
Flags​:
   category=?
   severity=high
---
Site configuration information for perl 5.12.0​:

Configured by eof at Tue May 11 08​:12​:38 BRT 2010.

Summary of my perl5 (revision 5 version 12 subversion 0) configuration​:

 Platform​:
   osname=linux, osvers=2.6.32-22-generic, archname=i686-linux
   uname='linux golden-eagle 2.6.32-22-generic #33-ubuntu smp wed apr 28
13​:27​:30 utc 2010 i686 gnulinux '
   config_args='-de'
   hint=recommended, useposix=true, d_sigaction=define
   useithreads=undef, usemultiplicity=undef
   useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
   use64bitint=undef, use64bitall=undef, uselongdouble=undef
   usemymalloc=n, bincompat5005=undef
 Compiler​:
   cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
   optimize='-O2',
   cppflags='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include'
   ccversion='', gccversion='4.4.3', gccosandvers=''
   intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
   d_longlong=define, longUse of uninitialized value $category in
concatenation (.) or string at /usr/local/bin/perlbug line 645.
Use of uninitialized value $severity in concatenation (.) or string at
/usr/local/bin/perlbug line 645.
---
Flags​:
   category=
   severity=high
---
Site configuration information for perl 5.12.0​:

Configured by eof at Tue May 11 08​:12​:38 BRT 2010.

Summary of my perl5 (revision 5 version 12 subversion 0) configuration​:

 Platform​:
   osname=linux, osvers=2.6.32-22-generic, archname=i686-linux
   uname='linux golden-eagle 2.6.32-22-generic #33-ubuntu smp wed apr 28
13​:27​:30 utc 2010 i686 gnulinux '
   config_args='-de'
   hint=recommended, useposix=true, d_sigaction=define
   useithreads=undef, usemultiplicity=undef
   useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
   use64bitint=undef, use64bitall=undef, uselongdouble=undef
   usemymalloc=n, bincompat5005=undef
 Compiler​:
   cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
   optimize='-O2',
   cppflags='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include'
   ccversion='', gccversion='4.4.3', gccosandvers=''
   intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
   d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
   ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
   alignbytes=4, prototype=define
 Linker and Libraries​:
   ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
   libpth=/usr/local/lib /lib /usr/lib /usr/lib64
   libs=-lnsl -ldl -lm -lcrypt -lutil -lc
   perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
   libc=/lib/libc-2.11.1.so, so=so, useshrplib=false, libperl=libperl.a
   gnulibc_version='2.11.1'
 Dynamic Linking​:
   dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
   cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib
-fstack-protector'

Locally applied patches​:

---
@​INC for perl 5.12.0​:
   /usr/local/lib/perl5/site_perl/5.12.0/i686-linux
   /usr/local/lib/perl5/site_perl/5.12.0
   /usr/local/lib/perl5/5.12.0/i686-linux
   /usr/local/lib/perl5/5.12.0
   .

---
Environment for perl 5.12.0​:
   HOME=/home/eof
   LANG=en_US.utf8
   LANGUAGE (unset)
   LD_LIBRARY_PATH (unset)
   LOGDIR (unset)

PATH=/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games
   PERL_BADLANG (unset)
   SHELL=/bin/bashlongsize=8, d_longdbl=define, longdblsize=12
   ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
   alignbytes=4, prototype=define
 Linker and Libraries​:
   ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
   libpth=/usr/local/lib /lib /usr/lib /usr/lib64
   libs=-lnsl -ldl -lm -lcrypt -lutil -lc
   perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
   libc=/lib/libc-2.11.1.so, so=so, useshrplib=false, libperl=libperl.a
   gnulibc_version='2.11.1'
 Dynamic Linking​:
   dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
   cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib
-fstack-protector'

Locally applied patches​:

---
@​INC for perl 5.12.0​:
   /usr/local/lib/perl5/site_perl/5.12.0/i686-linux
   /usr/local/lib/perl5/site_perl/5.12.0
   /usr/local/lib/perl5/5.12.0/i686-linux
   /usr/local/lib/perl5/5.12.0
   .

---
Environment for perl 5.12.0​:
   HOME=/home/eof
   LANG=en_US.utf8
   LANGUAGE (unset)
   LD_LIBRARY_PATH (unset)
   LOGDIR (unset)

PATH=/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games
   PERL_BADLANG (unset)
   SHELL=/bin/bash

--
Hudson Flávio Vieira Mateus
7° período - Ciência da Computação
Universidade Federal de Lavras

Linux registered user #488195

--
"You don't mean odds and ends, you mean des curieux et des bouts",
corrected the manager.
-- Terry Pratchett, Hogfather

@p5pRT
Copy link
Author

p5pRT commented May 18, 2010

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented May 18, 2010

@rgs - Status changed from 'open' to 'rejected'

@p5pRT p5pRT closed this as completed May 18, 2010
@p5pRT
Copy link
Author

p5pRT commented May 18, 2010

From [email protected]

I've tested others cases and $number is used.

Anyway, try this​:

use 5.010;

$number = 2;

given ($number) {
  when (2) {
  say "2 here!";
  }
}

Well, I've seen in a book ("Learning Perl - Fifth Edition") that smart match
is comutative.

So, this another example too​:

use 5.010;

@​array = (1,2,3);

if (@​array ~~ 2) {
  say "Matched!";
}

This e-mail was tested in 5.10. First e-mail was tested in 5.12 too and
didn't work.

Hugs!

--
Hudson Flávio Vieira Mateus
7° período - Ciência da Computação
Universidade Federal de Lavras

Linux registered user #488195

@p5pRT
Copy link
Author

p5pRT commented May 18, 2010

From @rgarcia

On 18 May 2010 15​:18, Hudson Flavio V Mateus <hudson@​comp.ufla.br> wrote​:

I've tested others cases and $number is used.

Anyway, try this​:

use 5.010;

$number = 2;

given ($number) {
   when (2) {
       say "2 here!";
   }
}

Well, I've seen in a book ("Learning Perl - Fifth Edition") that smart match
is comutative.

No, it's not. It was in 5.10.0, but that caused problems, so in some
cases it's no longer commutative in 5.10.1 and 5.12.*. The perl
documentation remains the authoritative source for perl's behaviour.

@p5pRT
Copy link
Author

p5pRT commented May 19, 2010

From [email protected]

Really, sometimes works, sometimes no... =/

Thanks by attention!

On Tue, May 18, 2010 at 12​:14 PM, Rafael Garcia-Suarez <rgs@​consttype.org>wrote​:

On 18 May 2010 15​:18, Hudson Flavio V Mateus <hudson@​comp.ufla.br> wrote​:

I've tested others cases and $number is used.

Anyway, try this​:

use 5.010;

$number = 2;

given ($number) {
when (2) {
say "2 here!";
}
}

Well, I've seen in a book ("Learning Perl - Fifth Edition") that smart
match
is comutative.

No, it's not. It was in 5.10.0, but that caused problems, so in some
cases it's no longer commutative in 5.10.1 and 5.12.*. The perl
documentation remains the authoritative source for perl's behaviour.

--
Hudson Flávio Vieira Mateus
7° período - Ciência da Computação
Universidade Federal de Lavras

Linux registered user #488195

@p5pRT
Copy link
Author

p5pRT commented May 19, 2010

From @ikegami

On Tue, May 18, 2010 at 11​:43 AM, Hudson Flavio V Mateus <
hudson@​comp.ufla.br> wrote​:

Really, sometimes works, sometimes no... =/

It always works if the arguments are ordered as per the 5.10.1 and newer
documentation. Non-commutative functions aren't exactly rare. 2**3 is not
the same as 3**2, and f() || g() is not the same as g() || f().

There was a whole class of problems that could only be solved by removing
the commutativity. Sorry for the inconvenience that this change caused.

@p5pRT
Copy link
Author

p5pRT commented May 20, 2010

From [email protected]

"It always works if the arguments are ordered as per the 5.10.1 and newer
documentation. Non-commutative functions aren't exactly rare. 2**3 is not
the same as 3**2, and f() || g() is not the same as g() || f()."

Oh, yes. I agree with you in *this case*. But, in case of Perl smart match
~~, documentation Perl *5.10*, not .1 or newer, says that the order that I
was using was correct. See more​: <
http​://perldoc.perl.org/5.10.0/perlsyn.html#Switch-statements>, section
"Smart matching in detail". There says exactly "It is *always commutative*".

But take this out.

Thanks by attention!

On Wed, May 19, 2010 at 11​:43 AM, Eric Brine <ikegami@​adaelis.com> wrote​:

On Tue, May 18, 2010 at 11​:43 AM, Hudson Flavio V Mateus <
hudson@​comp.ufla.br> wrote​:

Really, sometimes works, sometimes no... =/

It always works if the arguments are ordered as per the 5.10.1 and newer
documentation. Non-commutative functions aren't exactly rare. 2**3 is not
the same as 3**2, and f() || g() is not the same as g() || f().

There was a whole class of problems that could only be solved by removing
the commutativity. Sorry for the inconvenience that this change caused.

--
Hudson Flávio Vieira Mateus
7° período - Ciência da Computação
Universidade Federal de Lavras

Linux registered user #488195

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant