Closed p5pRT closed 13 years ago
I was **tempted** to file this as a BUG (will explain)...
From the manpage: (perfunc on sprintf).
Unlike "printf"\, "sprintf" does not do what you probably mean when you pass it an array as your first argument. The array is given scalar context\, and instead of using the 0th element of the array as the format\, Perl will use the count of elements in the array as the format\, which is ***almost never useful***.
I would assert that this behavior goes against the "spirit of perl" to "always do the right thing". To do something that is "almost never useful" can "almost never be the right thing".
Is there some **REAL** good reason why sprintf should not behave/ be compatible with printf? I just wasted eh...maybe 10-15 minutes concocting a "printf" statement -- that I wanted to print to a variable\, that would be passed the format and args in array\, only to discover this *wart*.
**Either that\, or** have 'printf' be able to print to a variable! (which is a bit 'lame'\, considering that's the point of sprintf).
Why would the implementation / behavior of sprintf be different than printf. The whole point (I thought) was to be able to redirect output to a string instead of a file handle.
If that's is not the point then a workaround\, (actually\, it would be a more generally purpose solution)\, would be to implement/allow:
open($handle\, \$myvar\, ">");
then I could printf $handle. Could even:
open($handle\, \$myvar\, "\<>"); print $handle "hello world\n"; seek $handle 0\,SEEK_SET; while(\<$handle>) { print } (out:) hello world
.. and get file-semantic behavior from a var...
I actually like this 2nd idea\, but it DOESN't mean the 'wart' on sprintf's implementation should remain.
So *WAS* there some reason to make sprintf incompat w/printf in syntax-functionality? Doesn't seem to make alot of sense and seems to be an unnecessary resriction.
(I really was under the 'illusion/misunderstanding'\, that sprintf and printf were 'identical' except one took a file handle and the other sent output to a var...*doh!* (hits self over head?))...
BTW -- would it be 'useful' for me to submit an RFE for my 'side comment above'? I've thought about it's desirability before.
***Given***\, the increases in available memory\, being able to use a meg or more of 'memory' in a "var" as a "scratch file"\, doesn't seem at all like an unreasonable feature...
On Tue\, Sep 27\, 2011 at 5:36 PM\, Linda Walsh \perlbug\-followup@​perl\.orgwrote:
# New Ticket Created by Linda Walsh # Please include the string: [perl #100190] # in the subject line of all future correspondence about this issue. # \<URL: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=100190 >
This is a bug report for perl from perl-diddler@tlinx.org\, generated with the help of perlbug 1.39 running under perl 5.12.3.
----------------------------------------------------------------- [Please describe your issue here]
I was **tempted** to file this as a BUG (will explain)...
From the manpage: (perfunc on sprintf).
Unlike "printf"\, "sprintf" does not do what you probably mean when you pass it an array as your first argument\. The array is given scalar context\, and instead of using the 0th element of the array as the format\, Perl will use the count of elements in the array as the format\, which is \*\*\*almost never useful\*\*\*\.
I would assert that this behavior goes against the "spirit of perl" to "always do the right thing". To do something that is "almost never useful" can "almost never be the right thing".
Is there some **REAL** good reason why sprintf should not behave/ be compatible with printf? I just wasted eh...maybe 10-15 minutes concocting a "printf" statement -- that I wanted to print to a variable\, that would be passed the format and args in array\, only to discover this *wart*.
**Either that\, or** have 'printf' be able to print to a variable! (which is a bit 'lame'\, considering that's the point of sprintf).
Why would the implementation / behavior of sprintf be different than printf. The whole point (I thought) was to be able to redirect output to a string instead of a file handle.
If that's is not the point then a workaround\, (actually\, it would be a more generally purpose solution)\, would be to implement/allow:
open\($handle\, \\$myvar\, ">"\);
then I could printf $handle. Could even:
open\($handle\, \\$myvar\, "\<>"\); print $handle "hello world\\n"; seek $handle 0\,SEEK\_SET; while\(\<$handle>\) \{ print \}
(out:) hello world
.. and get file-semantic behavior from a var...
I actually like this 2nd idea\, but it DOESN't mean the 'wart' on sprintf's implementation should remain.
So *WAS* there some reason to make sprintf incompat w/printf in syntax-functionality? Doesn't seem to make alot of sense and seems to be an unnecessary resriction.
(I really was under the 'illusion/misunderstanding'\, that sprintf and printf were 'identical' except one took a file handle and the other sent output to a var...*doh!* (hits self over head?))...
BTW -- would it be 'useful' for me to submit an RFE for my 'side comment above'? I've thought about it's desirability before.
***Given***\, the increases in available memory\, being able to use a meg or more of 'memory' in a "var" as a "scratch file"\, doesn't seem at all like an unreasonable feature...
[Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=wishlist --- This perlbug was built using Perl 5.12.3 - Fri May 6 13:31:41 UTC 2011 It is being executed now by Perl 5.12.3 - Fri May 6 13:26:30 UTC 2011.
Site configuration information for perl 5.12.3:
Configured by abuild at Fri May 6 13:26:30 UTC 2011.
Summary of my perl5 (revision 5 version 12 subversion 3) configuration:
Platform: osname=linux\, osvers=2.6.36\, archname=x86_64-linux-thread-multi uname='linux build33 2.6.36 #1 smp 2011-02-21 10:34:10 +0100 x86_64 x86_64 x86_64 gnulinux ' config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm -Duseshrplib=true -Doptimize=-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -Wall -pipe -Accflags=-DPERL_USE_SAFE_PUTENV' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=define\, use64bitall=define\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='cc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -Wall -pipe'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector' ccversion=''\, gccversion='4.5.1 20101208 [gcc-4_5-branch revision 167585]'\, gccosandvers='' intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16 ivtype='long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=8\, prototype=define Linker and Libraries: ld='cc'\, ldflags =' -L/usr/local/lib64 -fstack-protector' libpth=/lib64 /usr/lib64 /usr/local/lib64 libs=-lm -ldl -lcrypt -lpthread perllibs=-lm -ldl -lcrypt -lpthread libc=/lib64/libc-2.11.3.so\, so=so\, useshrplib=true\, libperl=libperl.so gnulibc_version='2.11.3' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib/perl5/5.12.3/x86_64-linux-thread-multi/CORE' cccdlflags='-fPIC'\, lddlflags='-shared -L/usr/local/lib64 -fstack-protector'
Locally applied patches:
--- @INC for perl 5.12.3: /usr/lib/perl5/site_perl/5.12.3/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.12.3 /usr/lib/perl5/vendor_perl/5.12.3/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.12.3 /usr/lib/perl5/5.12.3/x86_64-linux-thread-multi /usr/lib/perl5/5.12.3 .
--- Environment for perl 5.12.3: HOME=/home/law LANG=en_US.UTF-8 LANGUAGE (unset) LC_CTYPE=en_US.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset)
PATH=.:/sbin:/usr/local/sbin:/opt/lsb/bin:/home/law/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/opt/kde3/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin:/usr/lib/qt3/bin:/usr/sbin PERL_BADLANG (unset) SHELL=/bin/bash
Uh\, you can already do all the stuff you request\, y'know:
my @arr = ( "%s\n"\, "hullo" ); my $result = sprintf $arr[0]\, $arr[1..$#etc]; say $result;
Or if you think that's ugly\, you can do this in blead: my @arr = ( "%s\n"\, "hullo" ); my $result =&CORE::sprintf(@arr); say $result;
Printing to a scalar has also been in core for a while: open my $fh\, ">"\, \my $scalar or die $!; say { $fh } "hullo"; close($fh); say $scalar;
I wouldn't call it a wart\, any more than I'd call anything that uses prototypes a wart. Admittedly it's counterintuitive at first\, but expecting sprintf @arr to work would mean that open @arr should also work\, and so on; That road leads to madness.
The RT System itself - Status changed from 'new' to 'open'
Linda Walsh (via RT) \perlbug\-followup@​perl\.org writes:
I would assert that this behavior goes against the "spirit of perl" to "always do the right thing". To do something that is "almost never useful" can "almost never be the right thing".
+1
-- Johan
On Tue\, Sep 27\, 2011 at 4:36 PM\, Linda Walsh \perlbug\-followup@​perl\.orgwrote:
Is there some **REAL** good reason why sprintf should not behave/ be compatible with printf?
Actually\, printf is really the odd one. Builtins tend to have precise prototypes. printf doesn't have a prototype because of it's special parsing rules (e.g. printf { $fh } $pat\, @args).
If there was something to fix\, I'd lean towards changing printf. The fact that things can go horribly wrong when you don't pass a format is a good thing.
Ways of using sprintf when the format is in $arg[0]:
my $format = shift(@args); sprintf($format\, @args)
or
sprintf($args[0]\, @args[1..$#args])
or
sprintf(shift(@args)\, @args)
Eric Brine \ikegami@​adaelis\.com writes:
Ways of using sprintf when the format is in $arg[0]:
Yes\, we all know that. It's just stupid you can't write:
sub my_printf { print ">> " . sprintf(@_) }
but need
sub my_printf { print ">> " . sprintf( $_[0]\, @_[1..$#_] ) }
(OTOH\, this *does* look like Real Perl [tm] ... )
-- Johan
Brian Fraser wrote:
Uh\, you can already do all the stuff you request\, y'know:
my @arr = ( "%s\n"\, "hullo" ); my $result = sprintf $arr[0]\, $arr[1..$#etc]; say $result;
(I thought 'say' was deprecated? Seems like adding a keyword just to add on some desired line ending is a road to certain madness ... but .. hey\, ;-).
Ya know...for someone who talks like what they think they know what they are talking about\, they might wanna check their examples before telling people that they can do "XXX"\, cuz your example doesn't work (and I wasted a bit of time thinking you knew what you were talking about! (dictionary\, gullible: me).
So here's the stuff one would have to go through to get around this "WART":
"sub msg()"\, is an all-around msg routine that * adds newlines if you don't have one * can take an errno value as 1st arg and use the msg as output to die * take the 1st non errno value as an option format for the rest of the args; * else will print all the strings\, sep w/default OFS (null by default)\, so spaces are responsiblity of the user.
Considering it was written in an afternoon (after wasting much of it trying to hack around sprintf's limitations\, (not to mention the $arname[1..$#arname] not working as some suggested)\, don'texpect miracles. However\, _primitive_ cmdline testing shows that it demonstrates the beauty of sprintf's versatility compared to printf (!!NOT!!).
If you don't like my code style\, may you rot in Microsoft's laboratories!
#!/usr/bin/perl -w use 5.12.0; use Fatal;
use Readonly; sub RO(\[$@%]@) { goto &Readonly }
sub msg(@) { my @mp=@_; my $errno = shift @mp if $mp[0] =~ /^[-0-9]+$/; # do we have a status?
if (defined $mp[0] and $mp[0] =~ m{(^.*(?:(?:%|(?:[-\d.][a-zAA-Z]))|%)|\\).*$}) { $mp[0] =~ s{^(.*?)(?:\\n)?$}{$1}; if ($errno) { $mp[0] .= "\, Err=%s\n"; #add errno print to format w/NL $!=$errno; push @mp\, "$!"; # and add errno as last arg if (0) { # if this worked\, would make life simple... die sprintf @mp; } elsif (0) { #what lamer thought this worked in 5.12.0? die sprintf $mp[0]\, $mp[1..$#mp]; } elsif (0) { # this only works for 2 args+err code\, so also broken die sprintf $mp[0]\, $mp[1]\, $mp[2]\, $mp[3]; } else { # to handle var# args seems like eval is answer...? my $hack='sprintf "'. $mp[0] .'"\, '; for (my $i=1; $i\<=$#mp; ++$i) { $hack .= '\, $mp['."$i".']'; } $hack .= ';'."\n"; die eval "$hack"; } } else { $mp[0] .= "\n"; printf @mp; }
} else { return undef unless defined $mp[0]; chomp $mp[$#mp]; #noformat so chomp any 'nl's off the last arg # if we have an err\, then push printing of it onto end\, # else restore NL ($!=$errno\, push @mp\, "\, Err=$!\n") if $errno;
if ($errno) { die join $\, ? $\, : ""\, @mp; } else { print @mp\,"\n"; } return 1; } ## end sub msg($@) } ## end sub msg($@)
#test code msg @ARGV;
Or if you think that's ugly\, you can do this in blead: my @arr = ( "%s\n"\, "hullo" ); my $result =&CORE::sprintf(@arr); say $result;
Like bleeding helps me...hey your prev example doesn't work...maybe it only worked while bleeding too? ;-)
Printing to a scalar has also been in core for a while: open my $fh\, ">"\, \my $scalar or die $!; say { $fh } "hullo"; close($fh); say $scalar;
I'll reserve judgement on that until I've tried it\, give my history with a few other things you said were working...
I wouldn't call it a wart\, any more than I'd call anything that uses prototypes a wart.
You mean the prototypes that are 'awesome' and the only advice on them is: it's probably best to prototype new functions... [as opposed to trying to retrofit old ones]...
If every function since that was written was prototyped.... everything would be (in the camel book and manpage)..
Admittedly it's counterintuitive at first\,
yup ... counterintuitive is right!...That's not Perl spirit\, which is just supposed to "do the right thing"(c)-Perl (and something useful!)...
but expecting sprintf @arr to work would mean that open @arr should also work\, and so on; That road leads to madness. open @arr would work? Why? It's NOT a simple list of scalers... It's first arg is something to be *written to*. Yeah\, I could see the argument\, but\, realistically\, I'm looking at a command that ostensibly takes a list of scalars. There is no special type in perl (that I'm aware of)\, call 'FORMAT STRING'....
On Wed\, Sep 28\, 2011 at 04:27:23PM -0700\, Linda W wrote:
Brian Fraser wrote:
Uh\, you can already do all the stuff you request\, y'know:
my @arr = ( "%s\n"\, "hullo" ); my $result = sprintf $arr[0]\, $arr[1..$#etc]; say $result; ---- (I thought 'say' was deprecated? Seems like adding a keyword just to add on some desired line ending is a road to certain madness ... but .. hey\, ;-). ---- Ya know...for someone who talks like what they think they know what they are talking about\, they might wanna check their examples before telling people that they can do "XXX"\, cuz your example doesn't work (and I wasted a bit of time thinking you knew what you were talking about! (dictionary\, gullible: me).
This was just a typo - it should have been @arr[1..$#arr]\, not $arr[1..$#etc]. With that change\, it works fine.
-doy
On Thu\, Sep 29\, 2011 at 1:27 AM\, Linda W \perl\-diddler@​tlinx\.org wrote:
Ya know...for someone who talks like what they think they know what they are talking about\, they might wanna check their examples before telling people that they can do "XXX"\, cuz your example doesn't work (and I wasted a bit of time thinking you knew what you were talking about! Â (dictionary\, gullible: me).
Dear Linda\,
Could you please refrain from stabbing people who try to help you? The fact that they posted code that's not entirely correct does not justify personal attacks.
Thanks you\,
Leon
* Linda W \perl\-diddler@​tlinx\.org [2011-09-28T19:27:23]
my @arr = ( "%s\n"\, "hullo" ); my $result = sprintf $arr[0]\, $arr[1..$#etc]; say $result; [ ... ]
Ya know...for someone who talks like what they think they know what they are talking about\, they might wanna check their examples before telling people that they can do "XXX"\, cuz your example doesn't work (and I wasted a bit of time thinking you knew what you were talking about! (dictionary\, gullible: me).
There is no call for this kind of attitude. If we're all going to work together\, I think we can all try to be polite.
The response had a small typo. It just shows that turning (@arr) into ($head\, @rest) is trivial\, and that there is no massive machinery needed to do it.
It may be unfortunate that this builtin can't work the way you want\, but it has been this way for ages and is not really something that can be changed without serious disruption. Or\, to be more blunt\, I am fairly certain that it is simply not going to change. That's okay because you can write:
sub mysprintf { sprintf( $_[0]\, @_[ 1 .. $#_ ] ); }
my @arr = ('Foo %s'\, 123); print mysprintf(@arr);
The correct action is probably the addition of "printf EXPR" to printf's docs\, and a caveat about the lack of that form to sprintf's docs.
-- rjbs
On Wed\, Sep 28\, 2011 at 8:27 PM\, Linda W \perl\-diddler@​tlinx\.org wrote:
(I thought 'say' was deprecated? Seems like adding a keyword just to add on some desired line ending is a road to certain madness ... but .. hey\, ;-).
I don't think so? It's relatively new\, and used all the time in Modern Perl\, which came out less than a year ago. Plus it's a soft keyword\, enabled by a use version/feature. Seems like we ought to be encouraging more of these. (it's also lovely for marketing. Ruby has puts. Python adds it automatically to print. We have say.)
Ya know...for someone who talks like what they think they know what they are talking about\, they might wanna check their examples before telling people that they can do "XXX"\, cuz your example doesn't work (and I wasted a bit of time thinking you knew what you were talking about! (dictionary\, gullible: me).
They totally work\, once you run them under strict and fix them :P See doy's reply. Sorry about that.
So here's the stuff one would have to go through to get around this "WART":
"sub msg()"\, is an all-around msg routine that * adds newlines if you don't have one * can take an errno value as 1st arg and use the msg as output to die * take the 1st non errno value as an option format for the rest of the args; * else will print all the strings\, sep w/default OFS (null by default)\, so spaces are responsiblity of the user.
Considering it was written in an afternoon (after wasting much of it trying to hack around sprintf's limitations\, (not to mention the $arname[1..$#arname] not working as some suggested)\, don'texpect miracles. However\, _primitive_ cmdline testing shows that it demonstrates the beauty of sprintf's versatility compared to printf (!!NOT!!).
If you don't like my code style\, may you rot in Microsoft's laboratories!
#!/usr/bin/perl -w use 5.12.0; use Fatal;
use Readonly; sub RO(\[$@%]@) { goto &Readonly }
sub msg(@) { my @mp=@_; my $errno = shift @mp if $mp[0] =~ /^[-0-9]+$/; # do we have a status?
if (defined $mp[0] and $mp[0] =~ m{(^.*(?:(?:%|(?:[-\d.][a-zAA-Z]))|%)|\\).*$}) { $mp[0] =~ s{^(.*?)(?:\\n)?$}{$1}; if ($errno) { $mp[0] .= "\, Err=%s\n"; #add errno print to format w/NL $!=$errno; push @mp\, "$!"; # and add errno as last arg if (0) { # if this worked\, would make life simple... die sprintf @mp; } elsif (0) { #what lamer thought this worked in 5.12.0? die sprintf $mp[0]\, $mp[1..$#mp]; } elsif (0) { # this only works for 2 args+err code\, so also broken die sprintf $mp[0]\, $mp[1]\, $mp[2]\, $mp[3]; } else { # to handle var# args seems like eval is answer...? my $hack='sprintf "'. $mp[0] .'"\, '; for (my $i=1; $i\<=$#mp; ++$i) { $hack .= '\, $mp['."$i".']'; } $hack .= ';'."\n"; die eval "$hack"; } } else { $mp[0] .= "\n"; printf @mp; }
} else { return undef unless defined $mp[0]; chomp $mp[$#mp]; #noformat so chomp any 'nl's off the last arg # if we have an err\, then push printing of it onto end\, # else restore NL ($!=$errno\, push @mp\, "\, Err=$!\n") if $errno;
if ($errno) { die join $\, ? $\, : ""\, @mp; } else { print @mp\,"\n"; } return 1; } ## end sub msg($@) } ## end sub msg($@)
#test code msg @ARGV;
That's ugly. :)
Like bleeding helps me...hey your prev example doesn't work...maybe it only worked while bleeding too? ;-)
Well\, maybe your physician is a bit wacky and had you do some bloodletting. But I'd report him in that case.
You mean the prototypes that are 'awesome' and the only advice on them is: it's probably best to prototype new functions... [as opposed to trying to retrofit old ones]...
If every function since that was written was prototyped.... everything would be (in the camel book and manpage)..
That's hardly my point. In fact\, that's a huge strawman. Prototypes suck -- except when they don't. The only advice is not to use them[0]. But they do have their place -- I would much rather use grep or map followed by a block than by a sub declaration\, for example\, even if it's only a couple of extra characters.
I had no idea about that line in perlsub though. I kind of want it removed now\, but that's another topic for another time.
yup ... counterintuitive is right!...That's not Perl spirit\, which is just supposed to "do the right thing"(c)-Perl (and something useful!)...
It certainly does the right thing... Just not for you. I imagine Larry thought it made sense\, back in the day\, and changing ages-old behavior under people's feet isn't exactly nice\, so chances are this isn't going to happen. You are welcome to fix it and put it on CPAN though. In fact\, here you go\, something to get you started: BEGIN { *CORE::GLOBAL::sprintf = sub { CORE::sprintf( $_[0]\, @_[ 1 .. $#_ ] ); } }
open @arr would work? Why? It's NOT a simple list of scalers... It's first arg is something to be *written to*. Yeah\, I could see the argument\, but\, realistically\, I'm looking at a command that ostensibly takes a list of scalars.
Eh. my @list = ( q{\, }\, 1..10 ); say join @list; #whoops
Same with pack\, link\, etcetera. Basically\, you are attempting to treat built-ins as unprototyped functions\, which sounds remarkably like a "Doctor\, it hurts when I do this" situation. Either stop doing that\, or use the &CORE:: magicks with bleadperl.
There is no special type in perl (that I'm aware of)\,
call 'FORMAT STRING'....
Well\, to be pedantic\, sure there is. But I wouldn't read the "sprintf FORMAT\, LIST" description in the docs so literally\, otherwise sprintf's first argument would be:
format MIND = slightly disturbed .
sprintf *MIND{FORMAT}\, ...;
[0] http://www.perlmonks.org/?node_id=861966
Leon Timmermans wrote:
On Thu\, Sep 29\, 2011 at 1:27 AM\, Linda W \perl\-diddler@​tlinx\.org wrote:
Ya know...for someone who talks like what they think they know what they are talking about\, they might wanna check their examples before telling people that they can do "XXX"\, cuz your example doesn't work (and I wasted a bit of time thinking you knew what you were talking about! (dictionary\, gullible: me).
Dear Linda\,
Could you please refrain from stabbing people who try to help you? The fact that they posted code that's not entirely correct does not justify personal attacks.
Can you tell me what about the above could possibly be taken personally?
Is it not true that they talk like someone who knows what they are talking about?
Is it wrong to say they should check their examples before telling other people ho to use them?
I called my self gullible\, which you might consider personal\, but I think that's between me and myself -- and I certainly couldn't make it work.
It didn't occur to me to think he was talking about array slices.
'STABBING PEOPLE'...WTF? get a life Leon. Yeah\, you can take that as personally as you dealt it.
Thanks you\,
Leon
You're welcome\, you! *pblblblb*...(that means don't take the above as very personal (heck\, I don't even know you...but stop thinking the world is made of eggshells!!))
linda
Ricardo Signes via RT wrote:
* Linda W \perl\-diddler@​tlinx\.org [2011-09-28T19:27:23]
Ya know...for someone who talks like what they think they know what they are talking about\, they might wanna check their examples before telling people that they can do "XXX"\, cuz your example doesn't work (and I wasted a bit of time thinking you knew what you were talking about! (dictionary\, gullible: me).
There is no call for this kind of attitude. If we're all going to work together\, I think we can all try to be polite.
ARG!? What is it with all the delicate personalities...I didn't call him any names. I didn't swear\, I only spoke 100% truth -- no opinion. 'person thinks they know what they are talking about (and they may or may not\, DIDN'T SAY!)\, BUT regardless\, they should check the examples they hand off to others to use. You call that advice "harsh"\, or saying that the example they have didn't work\, "harsh". I took him at his word because I thought he knew what he was talking about -- and might have been referring to features I knew nothing about -- i.e. I had a higher estimation of his perl experience than my own.
I got caught w/my pants down\, that's all...I pointed the blame at me as much as any -- i.e. who did I call gullible (I.e. accepting things 'at face value too often' because they believe others might know more)?.... I'm all too willing to do that and just a bit too willing to NOT examine everything as critically at certain times. I'm sorry I admitted my gullibility\, I know that's no type of attitude\, but it is true -- I tend to be a bit believing in people too much. (what a sap I must sound like)....whatever. Kumbaya!
It's NOT that big a deal (I doubt any one who has even a little self-esteem would have lent any harsh weight to my words...they weren't scathing or pointed\, NOR a personal attack...doesn't everyone make mistakes?
I get chided if I release something that isn't right -- if not by others\, mercilessly by myself\, but I live through it...(you should hear the harsh attitude I give myself\, if you wanna let your ears burn!...)... most people don't wanna be anywhere near me when I launch into myself... ;-/
:-?
* Linda Walsh \perlbug\-followup@​perl\.org [2011-09-27 22:40]:
From the manpage: (perfunc on sprintf).
Unlike "printf"\, "sprintf" does not do what you probably mean when you pass it an array as your first argument\. The array is given scalar context\, and instead of using the 0th element of the array as the format\, Perl will use the count of elements in the array as the format\, which is \*\*\*almost never useful\*\*\*\.
I would assert that this behavior goes against the "spirit of perl" to "always do the right thing". To do something that is "almost never useful" can "almost never be the right thing".
Is there some **REAL** good reason why sprintf should not behave/ be compatible with printf?
No. There isnât.
I just wasted eh...maybe 10-15 minutes concocting a "printf" statement -- that I wanted to print to a variable\, that would be passed the format and args in array\, only to discover this *wart*.
Sorry for the time you wasted.
**Either that\, or** have 'printf' be able to print to a variable! (which is a bit 'lame'\, considering that's the point of sprintf).
Why would the implementation / behavior of sprintf be different than printf. The whole point (I thought) was to be able to redirect output to a string instead of a file handle.
There is no good reason. It just is.
If that's is not the point then a workaround\, (actually\, it would be a more generally purpose solution)\, would be to implement/allow:
open\($handle\, \\$myvar\, ">"\);
then I could printf $handle. Could even:
open\($handle\, \\$myvar\, "\<>"\); print $handle "hello world\\n"; seek $handle 0\,SEEK\_SET; while\(\<$handle>\) \{ print \}
(out:) hello world
.. and get file-semantic behavior from a var...
I actually like this 2nd idea
Thatâs gross. Please donât do that. Think of the poor wretch who will work on the code after you.
but it DOESN't mean the 'wart' on sprintf's implementation should remain.
Neither does it mean the wart should change. Itâs not relevant.
If the behaviour of sprintf were to change\, then a lot more people than you would have a lot more than 15 of their minutes wasted; so moreâs the pity that it has to stay.
So *WAS* there some reason to make sprintf incompat w/printf in syntax-functionality? Doesn't seem to make alot of sense and seems to be an unnecessary resriction.
Itâs just an accident of history.
(I really was under the 'illusion/misunderstanding'\, that sprintf and printf were 'identical' except one took a file handle and the other sent output to a var...*doh!* (hits self over head?))...
Welcome to the wonderful world of software\, full of annoying surprises like that. Software sucks.
BTW -- would it be 'useful' for me to submit an RFE for my 'side comment above'? I've thought about it's desirability before.
***Given***\, the increases in available memory\, being able to use a meg or more of 'memory' in a "var" as a "scratch file"\, doesn't seem at all like an unreasonable feature...
Itâs not relevant.
Regards\, -- Aristotle Pagaltzis // \<http://plasmasturm.org/>
@cpansprout - Status changed from 'open' to 'rejected'
On Wed\, Sep 28\, 2011 at 8:51 AM\, Johan Vromans \jvromans@​squirrel\.nl wrote:
Eric Brine \ikegami@​adaelis\.com writes:
Ways of using sprintf when the format is in $arg[0]:
Yes\, we all know that. It's just stupid you can't write:
sub my_printf { print ">> " . sprintf(@_) }
but need
sub my_printf { print ">> " . sprintf( $_[0]\, @_[1..$#_] ) }
(OTOH\, this *does* look like Real Perl [tm] ...
Except the same thing applies to every single builtin (e.g. length\, splice\, substr\, exit\, etc.)
On Wed\, Sep 28\, 2011 at 7:27 PM\, Linda W \perl\-diddler@​tlinx\.org wrote:
but expecting sprintf @arr to work would mean that open @arr should also
work\, and so on; That road leads to madness.
open @arr would work? Why? It's NOT a simple list of scalers...
First\, that's not true. C\
Secondly\, you just answered your own question. What's special is the syntax.
c\
It's first arg is something to be *written to*.
Actually\, it's not. The first operand is a file handle. C\
Even if it was being written to\, you think you can write to one scalar\, but not $args[0] which is also a scalar?
There is no special type in perl (that I'm aware of)\,
call 'FORMAT STRING'....
That's eaxctly what sprintf is not special and printf is.
Eric Brine via RT wrote:
On Wed\, Sep 28\, 2011 at 7:27 PM\, Linda W \perl\-diddler@​tlinx\.org wrote:
but expecting sprintf @arr to work would mean that open @arr should also
work\, and so on; That road leads to madness.
open @arr would work? Why? It's NOT a simple list of scalers...
First\, that's not true. C\
only takes scalars for operands.
open FOOBAR\, "file"\, "mode";
FOOBAR doesn't look like a simple scalar. Doesn't need quotes\, has no $ ... Why do you consider it a simple scalar?
Or:
open $scalar-target\, $scalar\, .....
Again\, the 1st can't be a R/O var\, it has to be a writeable var...it's not the same as the rest.
But in:
sprintf" FOOBAR\, "arg"\, $arg2\,[list]...
FOOBAR would be illegal -- (in strict)... it's not a a string constant\, and has no quotes. It is a read-only parameter passed to sprintf (by R/O\, I mean sprintf doesn't try to write to it. In printf it's similar compare the syntax:
printf [HANDLE] @list...
sprintf @list....
only difference about printf is it can take an optional handle where you can't use a colon.
There is no form of 'open' where it doesn't take a list (either literal or implied). The same is not true for printf -- as it can have the optional FH\, as the first param that is NOT part of a list.
Why there should be a feature in the language for sprintf to specifically disallow an array\, which would "almost never do anything useful"\, when it really wants a list at that posistion?
Can anyone think of some example where the 'length' of an array can be used as teh format string for the variables that follow? I.e. I see no reason why it couldn't go through a deprecation cycle (I thought I could come up with an example\, but it doesn't work\, so I have no clue how you could use such a feature. I.e.\, I tried:
simply forming "%s\n" which in hex would be: 0x0025730a\, or\, on an LE machine\, 0x000a5225\, would be that 4 bytes string in 1 32-bit word\, but perl keeps track that it isn't really to be interpreted as a string\, but as a number\, so all it does is print out the number:
perl -e 'my @ar; $#ar=0x000a5225; my $out=sprintf @ar\, "my string"; print "$out\n"; ' 676390
Bummer. But make for a good case about the change not breaking previous compat!
Secondly\, you just answered your own question. What's special is the syntax. c\
has a special syntax just like c\ \, which is why C\ bhves different than C\ \, C\ \, C\ \, etc. It's first arg is something to be *written to*.
Actually\, it's not. The first operand is a file handle. C\
and C\ write to the handle\, but not to the first arg.
open writes to the first\, print does not. Sorry for any confusion.
If you think open doesn't write to the file handle\, you are in error:
perl -e ' use Readonly; Readonly my $fh => undef; open $fh\, "/etc/passwd" || die "open failed: $!\n"; ' Modification of a read-only value attempted at -e line 4
Perl does write to the first arg in open.
Even if it was being written to\, you think you can write to one scalar\, but not $args[0] which is also a scalar?
What made you think that I thought that?
There is no special type in perl (that I'm aware of)\,
called 'FORMAT STRING'.... That's eaxctly what sprintf is not special and printf is.
printf is special in that it can take an optional\, *non-list*\, (i.e. not
something you can put in an array) arg. After that optional arg\, it takes
a list -- just like spritnf.
Lists can be represented by arrays.
"sprintf's" list can't accept an array\, even though it's arguments exactly the same list that can be passed to 'printf' for it's list parameters.
Thus it breaks the list-as array paradigm.
Thus I consider it a bug (though as it was designed that way\, I called it an RFE).
[Quoting Eric Brine\, on September 29 2011\, 18:21\, in "Re: [perl #100190] R"]
 sub my\_printf \{ print ">> " \. sprintf\(@​\_\) \} but need  sub my\_printf \{ print ">> " \. sprintf\( $\_\[0\]\, @​\_\[1\.\.$\#\_\] \) \}
Except the same thing applies to every single builtin (e.g. length\, splice\, substr\, exit\, etc.)
Which\, IMNSHO\, indicates there's something counter-intuitive with the way these builtins are handled.
-- Johan
On Thu\, Sep 29\, 2011 at 9:59 PM\, Linda Walsh \perl\-diddler@​tlinx\.org wrote:
Eric Brine via RT wrote:
On Wed\, Sep 28\, 2011 at 7:27 PM\, Linda W \perl\-diddler@​tlinx\.org wrote:
but expecting sprintf @arr to work would mean that open @arr should also
work\, and so on; That road leads to madness.
open @arr would work? Why? It's NOT a simple list of scalers...
First\, that's not true. C\
only takes scalars for operands. ----
open FOOBAR\, "file"\, "mode";
FOOBAR doesn't look like a simple scalar. Doesn't need quotes\, has no $ ... Why do you consider it a simple scalar?
It's a glob\, which is a scalar.
Or:
open $scalar-target\, $scalar\, .....
Again\, the 1st can't be a R/O var\, it has to be a writeable var...it's not the same as the rest.
Actually\, it can be a read-only var as far as the function call is concerned. The call will eventually fail\, but open will get called.
But in:
sprintf" FOOBAR\, "arg"\, $arg2\,[list]...
FOOBAR would be illegal -- (in strict)...
Yes\, I've already said open had different syntax rules.
mean sprintf doesn't try to write to it. In printf it's similar compare the syntax:
printf [HANDLE] @list...
sprintf @list....
only difference about printf is it can take an optional handle where you can't use a colon.
colon? What? No idea what this means.
As I've already said\, the only difference is that printf's parametrs cannot be represented by a prototype.
There is no form of 'open' where it doesn't take a list
No idea what this means.
Why there should be a feature in the language for sprintf to specifically disallow an array\, which would "almost never do anything useful"\, when it really wants a list at that posistion?
All builtins use prototypes where possible.
Prototypes are awful\, but all builtins use prototypes\, and that cannot be changed now.
Can anyone think of some example where the 'length' of an array can be
used as teh format string for the variables that follow?
You're being absurd. Do you really think that's the reason prototypes are being used?
If you think open doesn't write to the file handle\, you are in error:
You misquoted me.
Even if it was being written to\, you think you can write to one scalar\,
but not $args[0] which is also a scalar?
----
What made you think that I thought that?
You said you couldn't pass an array because the first arg was written to. I showed why that makes no sense.
called 'FORMAT STRING'....
That's eaxctly what sprintf is not special and printf is.
There is no special type in perl (that I'm aware of)\, --- printf is special in that it can take an optional\, *non-list*\, (i.e. not something you can put in an array) arg. After that optional arg\, it takes a list -- just like spritnf.
Not relevant. printf is special because it's calling syntax cannot be represented by a prototype. I've already explained that.
Lists can be represented by arrays.
No. That makes no sense.
"sprintf's" list can't accept an array\,
Not true. It can't accept just an array.
even though it's arguments
exactly the same list that can be passed to 'printf' for it's list parameters.
Yes\, it's not by choice\, but because printf cannot have a prototype. I've already explained that.
Thus it breaks the list-as array paradigm.
List aren't arrays. Arrays aren't no lists. There is no such paradigm.
Thus I consider it a bug (though as it was designed that way\, I called it an RFE).
There are so many errors in this post\, I cannot take anything from it.
- Eric
On Fri\, Sep 30\, 2011 at 1:52 AM\, Johan Vromans \jvromans@​squirrel\.nl wrote:
[Quoting Eric Brine\, on September 29 2011\, 18:21\, in "Re: [perl #100190] R"]
sub my\_printf \{ print ">> " \. sprintf\(@​\_\) \} but need sub my\_printf \{ print ">> " \. sprintf\( $\_\[0\]\, @​\_\[1\.\.$\#\_\] \) \}
Except the same thing applies to every single builtin (e.g. length\, splice\, substr\, exit\, etc.)
Which\, IMNSHO\, indicates there's something counter-intuitive with the way these builtins are handled.
Yes\, prototypes are recognised as being problematic.
On Fri\, Sep 30\, 2011 at 04:44\, Eric Brine \ikegami@​adaelis\.com wrote: snip
 open FOOBAR\, "file"\, "mode";
FOOBAR doesn't look like a simple scalar. Â Doesn't need quotes\, has no $ ... Why do you consider it a simple scalar?
It's a glob\, which is a scalar.
I could have sworn FOOBAR in that case was just a bareword (and there for just "FOOBAR") not a glob. I do know that
open "FOOBAR"\, ">"\, $file or die "could not open $file: $!";
works.
-- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.
Aristotle Pagaltzis wrote:
* Linda Walsh \perlbug\-followup@​perl\.org [2011-09-27 22:40]: Is there some **REAL** good reason why sprintf should not behave/ be compatible with printf?
No. There isnât.
I'm glad you agree\, it's a bug in the design of the language.
I just wasted eh...maybe 10-15 minutes concocting a "printf" statement -- that I wanted to print to a variable\, that would be passed the format and args in array\, only to discover this *wart*. Sorry for the time you wasted.
I did emphasize the trivial amount of time I wasted... i.e. it wasn't a huge deal...but I realized how ugly the problem was. Literally\, I had a routine that just passed an optional error code and list\, where the first arg could be a format or not\, to a general error routine -- then I realized I really wanted to call DIE instead of sprintf and exit\, and massage the string to interpret the error code as an '$ERRNO' in a string context.. The massaging part was doable\, but to get a string w/formatting that didn't use printf it really seemed like I should be able to take the LIST comprised of either a simple string\, or a format followed by it's args that was located in the rest of the @ARGS -- that I had been passing to printf in "printf STDERR\, @ARGV" => "die sprintf @ARGV";
In C\, those calls are much more parallel\, with different names to indicate what optional args are at the beginning\, but other than the otional args...they all take a uniform (same type) list of 'char * format\, ...'.
Since sprintf and printf both are documented to be implemented on top of the local [POSIX-compat] C library\, then a difference in their invocation\, from the documentation\, would be an error.
There is no good reason. It just is.
Usually those are things that need to be fixed. When I was told stuff like that as a child\, it usually involved religious issues that I questioned and ultimate refused to accept.
Thatâs gross. Please donât do that. Think of the poor wretch who will work on the code after you.
That's\, **usually**\, me. When I do something that is less than str8 forward\, I try to make sure it is well documented enough that I'll understand it in 'N' months\, as in 'N' months\, I'll remember nothing about why I did such -- have had it happen too many times NOT to document such. But it would have to be that it was algorithmically the right choice (more efficient\, flexible)\, not just for the sake of doing it.
but it DOESN't mean the 'wart' on sprintf's implementation should remain.
Neither does it mean the wart should change. Itâs not relevant. Of course it is relevant. If something is needlessly broken and can be fixed\, why would you just choose to live with it? If humans took that attitude as a whole\, society would never change.
If the behaviour of sprintf were to change\, then a lot more people than you would have a lot more than 15 of their minutes wasted; so moreâs the pity that it has to stay.
As demonstrated by later example\, trying to use it's existing behavior in any meaningful way fails\, so there is an extremely low probability of any existing code breaking if such a change were to be made. There have been other changes in perl code where old features have been deprecated and changed that would have been FAR more likely to cause an incompatibility that were changed because those features were considered 'warts' or roadblocks to forward progress. There was no 'pity' for them. There was only change and 'deprecation' when needed.
So *WAS* there some reason to make sprintf incompat w/printf in syntax-functionality? Itâs just an accident of history.
That you agree it's a mistake makes moving forward a far easier task...otherwise\, perl 5.12.0 would be bound to the same feature set as 4.0\, which fortunately\, is not the case.
Linda
Aristotle Pagaltzis wrote:
* Linda Walsh \perlbug\-followup@​perl\.org [2011-09-27 22:40]: Is there some **REAL** good reason why sprintf should not behave/ be compatible with printf?
No. There isnĂąÂÂt. ---- I'm glad you agree\, it's a bug in the design of the language.
Now you're just being unnecessarily silly. Just because you don't like something doesn't mean it is a bug.
--tom
On Fri\, Sep 30\, 2011 at 5:37 AM\, Chas. Owens \chas\.owens@​gmail\.com wrote:
On Fri\, Sep 30\, 2011 at 04:44\, Eric Brine \ikegami@​adaelis\.com wrote: snip
open FOOBAR\, "file"\, "mode";
FOOBAR doesn't look like a simple scalar. Doesn't need quotes\, has no $ ... Why do you consider it a simple scalar?
It's a glob\, which is a scalar.
I could have sworn FOOBAR in that case was just a bareword'
It gets compiled to a glob\, so
@args = (*FOOBAR\, '>'\, ...); open(@args)
would work without the prototype.
Tom Christiansen wrote:
I'm glad you agree\, it's a bug in the design of the language.
Now you're just being unnecessarily silly. Just because you don't like something doesn't mean it is a bug.
Well\, officially\, I did file it as an RFE (wishlist)... if you really wanna get serious about it and all.
But along the lines of silly:
Eric Brine via RT wrote:
On Wed\, Sep 28\, 2011 at 8:51 AM\, Johan Vromans \jvromans@​squirrel\.nl wrote
Yes\, we all know that. It's just stupid you can't write: sub my_printf { print ">> " . sprintf(@_) } but need sub my_printf { print ">> " . sprintf( $_[0]\, @_[1..$#_] ) } (OTOH\, this *does* look like Real Perl [tm] ... Except the same thing applies to every single builtin (e.g. length\, splice\, substr\, exit\, etc.
Hmm... Let's examine this strawman argument are any of these command that would take a list of scalars that are not written to?
length -- \<$> - takes 1 expression splice -- \<@>[$\,[$\,[list]]] -- ?! can't allow an array here\, how would you tell the difference between that and the 1 arg form? substr -- \<$\,$>[\,$[\,$] --- maybe\, but it's not a variable length list exit -- $ -- one expression
vs. printf [handle] \
sprintf \
But more importantly is that printf and sprintf are designed to do the same type of thing with those args -- they both want a format and optional vars that it uses to format a string sent to output or another string.
If there are other groups of calls that have similar syntax and functionality\, they\, possibly\, should also have similar calling requirements/restrictions.
I don't think anyone has put forth an argument as to why sprintf not be able to handle the same list-arguments as printf. There's been alot of deflection\, and hemming and hawing and trying to derail the discussion. A few others see the light as well. It's a trivial change. I'm asking what would be the harm in making two functions that provide similar functionality allow similar calling conventions.
I.e. why not just allow a list? Both know that they will NEVER look for the length of an array as a 'format' string...so it's hard to see why there's been such a kneejerk reaction against the idea.
On Sat\, Oct 1\, 2011 at 1:32 AM\, Linda W \perl\-diddler@​tlinx\.org wrote:
Tom Christiansen wrote:
I'm glad you agree\, it's a bug in the design of the language.
Now you're just being unnecessarily silly. Just because you don't like something doesn't mean it is a bug. ---- Well\, officially\, I did file it as an RFE (wishlist)... if you really wanna get serious about it and all.
But along the lines of silly:
Eric Brine via RT wrote:
On Wed\, Sep 28\, 2011 at 8:51 AM\, Johan Vromans \jvromans@​squirrel\.nl wrote
Yes\, we all know that. It's just stupid you can't write: sub my_printf { print ">> " . sprintf(@_) } but need sub my_printf { print ">> " . sprintf( $_[0]\, @_[1..$#_] ) } (OTOH\, this *does* look like Real Perl [tm] ... Except the same thing applies to every single builtin (e.g. length\, splice\, substr\, exit\, etc. ------ Hmm... Let's examine this strawman argument are any of these command that would take a list of scalars that are not written to?
length -- \<$> - takes 1 expression
Are you saying array cannot hold one element?
substr -- \<$\,$>[\,$[\,$] --- maybe\, but it's not a variable length list
By that logic\, neither is sprintf\, it's 1 scalar but a variable length list.
exit -- $ -- one expression
Are you saying array cannot hold one element?
But more importantly is that printf and sprintf are designed to do the
same type of thing with those args -- they both want a format and optional vars that it uses to format a string sent to output or another string.
Yes\, so\, printf should be like sprintf.
I.e. why not just allow a list?
Because sprintf takes a scalar plus a list\, and printf takes a handle/block plus a scalar plus a list.
I don't think anyone has put forth an argument as to why sprintf not be able
to handle the same list-arguments as printf.
Actually\, I did. The purpose of the sprintf prototype is to make it hard to accidentally write bad code. Removing the prototype will cause sprintf to fail more subtly when used incorrectly.
That leaves changing printf to be like sprintf. I don't know the technical reasons for why printf doesn't impose scalar context on the format arg.
Both know that they will NEVER look forthe length of an array as a 'format'
string
Of course not. It helps finding the missing format argument.
Eric Brine via RT wrote:
Hmm... Let's examine this strawman argument are any of these command that would take a list of scalars that are not written to?
length -- \<$> - takes 1 expression
Are you saying array cannot hold one element?
I'm saying that the argument to length is NOT a list. Therefore an array makes no sense. Where are the people who comment on silliness at this point?
substr -- \<$\,$>[\,$[\,$] --- maybe\, but it's not a variable length list
By that logic\, neither is sprintf\, it's 1 scalar but a variable length list.
?!? sprintf takes a variable length list just like printf does. The minimum number of params passed is determined by the 1st. Such is not true of substr\, which doesn't take a variable length list\, but always takes 2\, 3 or 4 params\, but no list of 0..[size that machine & perl will allow]. Again your example doesn't fit the paradigm.
exit -- $ -- one expression
Are you saying array cannot hold one element?
Are you saying 1 element IS an array? Are you saying exit can take more than one value?
If not\, and you pass it an array\, which value from the array do you return? Do you have or consider any logic to your pointless obstructionism? What is exit or length supposed to do with an array? Should length return the length of an array?\, or the length of the sum of the chars in the array? Or just the length of the 1st or what? you'd have to change the definition and function of length and exit to make either change.
What you are proposing are changes that would require redefining how those functions work.
What I am proposing clearly makes nor requires change in functional behavior.
Yes\, so\, printf should be like sprintf.
I.e. why not just allow a list?
Because sprintf takes a scalar plus a list\, and printf takes a handle/block plus a scalar plus a list.
You just hit the nail on the head. They both take a scalar\, comma separated from a list... indistinguishable from a list.
printf takes an optional\, and MOST IMPORTANTLY\, a **COMPLETELY ORTHOGONAL** syntax that cannot be mistaken for being part of a list.
I don't think anyone has put forth an argument as to why sprintf not be able to handle the same list-arguments as printf.
Actually\, I did. The purpose of the sprintf prototype is to make it hard to accidentally write bad code. Removing the prototype will cause sprintf to fail more subtly when used incorrectly.
Make it hard to write bad code (are you a perl hacker? 'sides that's what prototypes are for! ;-) [preventing!] ) How does it pass bad code? You CAN pass an array to it\, it just is BAD code -- it certainly doesn't throw an syntax error -- it allows an array there\, which\, "___is [almost]^ never useful__". (Note: word 'almost' bracketed with ^ to indicate editorial deletion\, as circling it and drawing a line out won't work\, and strike-through doesn't work in ascii...which seems to be std.bug input format; *idea*: Maybe the bug input form could allow wiki-like text markup??.....(*ducking before someone throws something at me*))
On Sat\, Oct 1\, 2011 at 1:18 PM\, Linda Walsh \perl\-diddler@​tlinx\.org wrote:
[...]You CAN pass an array to it\, it just is BAD code -- it certainly doesn't throw an syntax error -- it allows an array there\, which\, "___is [almost]^ never useful__". [...]
You know. That's actually true. There's a bug in a handful of modules because of this; See http://grep.cpan.me/?q=sprintf\s*\%28%3F\s*\%40 and http://www.google.com/codesearch#search/&q=sprintf\s*\%28 ?\s*\@%20lang:^perl$&type=cs Changing it takes two lines of code (regen/opcodes and t/op/cproto.t) and a regen\, plus doc/delta changes. I was under the impression that @ is a superset of $@\, so there's no lost functionality either -- I'm running (a very slow) make test right now\, and nothing is failing\, so this behavior wasn't even tested for! (or I haven't reached that part yet\, but op/sprintf.t and op/sprintf2.t passed without issues)
And it's not like prototypes haven't been changed before (to tchrist's chagrin\, e.g. http://www.nntp.perl.org/group/perl.perl5.porters/2011/04/msg171420.html).
So eh\, any reason why this can't be changed? If anyone needs a compat layer\, I imagine it's trivial enough to provide through Classic::Perl/Modern::Perl\, or somesuch.
On Wed\, Oct 5\, 2011 at 6:38 PM\, Brian Fraser \fraserbn@​gmail\.com wrote:
See http://grep.cpan.me/?q=sprintf\s*\%28%3F\s*\%40\<http://grep.cpan.me/?q=sprintf%5Cs*%5C%28%3F%5Cs*%5C%40>and http://www.google.com/codesearch#search/&q=sprintf\s*\%28\<http://www.google.com/codesearch#search/&q=sprintf%5Cs*%5C%28> ?\s*\@%20lang:^perl$&type=cs
..which reveals that the core itself gets this (probably) wrong\, in ext/B/t/terse.t. That seems to go unused\, though.
On Wed\, Oct 5\, 2011 at 11:38 PM\, Brian Fraser \fraserbn@​gmail\.com wrote:
And it's not like prototypes haven't been changed before (to tchrist's chagrin\, e.g. http://www.nntp.perl.org/group/perl.perl5.porters/2011/04/msg171420.html).
Most of the changes are completely backwards compatible (e.g. «(;$)» to «(_)» or «(\@)» to «(+)». A few made the prototype slightly stricter\, but not in ways that should break any working code (e.g. «($)» to «(\$)»). This does have the potential to break working code.
Not that I'd mind getting rid of most prototypes in builtins\, I'd just like them to be conditional on «use 5.016;»\, which won't be trivial AFAIK.
Leon
On Wed Oct 05 16:13:07 2011\, LeonT wrote:
On Wed\, Oct 5\, 2011 at 11:38 PM\, Brian Fraser \fraserbn@​gmail\.com wrote:
And it's not like prototypes haven't been changed before (to tchrist's chagrin\, e.g.
http://www.nntp.perl.org/group/perl.perl5.porters/2011/04/msg171420.html).
Most of the changes are completely backwards compatible
In fact\, most of the changes merely demonstrate how buggy prototype() has been in the past. Many of the prototypes it has returned (even in 5.14) do not represent how the function is actually parsed.
On Wed Oct 05 14:38:47 2011\, Hugmeir wrote:
On Sat\, Oct 1\, 2011 at 1:18 PM\, Linda Walsh \perl\-diddler@​tlinx\.org wrote:
[...]You CAN pass an array to it\, it just is BAD code -- it certainly doesn't throw an syntax error -- it allows an array there\, which\, "___is [almost]^ never useful__". [...]
You know. That's actually true. There's a bug in a handful of modules because of this; See http://grep.cpan.me/?q=sprintf\s*\%28%3F\s*\%40 and http://www.google.com/codesearch#search/&q=sprintf\s*\%28 ?\s*\@%20lang:^perl$&type=cs Changing it takes two lines of code (regen/opcodes and t/op/cproto.t) and a regen\, plus doc/delta changes. I was under the impression that @ is a superset of $@\, so there's no lost functionality either -- I'm running (a very slow) make test right now\, and nothing is failing\, so this behavior wasn't even tested for! (or I haven't reached that part yet\, but op/sprintf.t and op/sprintf2.t passed without issues)
And it's not like prototypes haven't been changed before (to tchrist's chagrin\, e.g. http://www.nntp.perl.org/group/perl.perl5.porters/2011/04/msg171420.html).
So eh\, any reason why this can't be changed?
Consider sprintf(get_format()\, @args). get_format might return something else in list context. Thatâs the kind of breakage we donât want.
Also\, does your experiment really work\, or do you mess up the stack in cases like this?
@a = ('%d'\, sprintf());
If anyone needs a compat layer\, I imagine it's trivial enough to provide through Classic::Perl/Modern::Perl\, or somesuch.
What would prototype(\&CORE::sprintf) return?
On Sun\, Oct 16\, 2011 at 4:02 AM\, Father Chrysostomos via RT \< perlbug-followup@perl.org> wrote:
Consider sprintf(get_format()\, @args). get_format might return something else in list context. Thatâs the kind of breakage we donât want.
Yeah. The same was pointed to me on IRC after I sent that\, which I hadn't considered at all. So I canned the experiment : )
But out of curiosity\, lemme dig it up and see what the answers for the rest of the mail would've been.
Also\, does your experiment really work\, or do you mess up the stack in cases like this?
@a = ('%d'\, sprintf());
Stack blown\, so that's another strike.
If anyone needs a compat layer\, I imagine it's trivial enough to provide through Classic::Perl/Modern::Perl\, or somesuch.
What would prototype(\&CORE::sprintf) return?
@
Father Chrysostomos via RT wrote:
Consider sprintf(get_format()\, @args). get_format might return something else in list context. Thatâs the kind of breakage we donât want.
Also\, does your experiment really work\, or do you mess up the stack in cases like this?
@a = ('%d'\, sprintf());
If anyone needs a compat layer\, I imagine it's trivial enough to provide through Classic::Perl/Modern::Perl\, or somesuch.
What would prototype(\&CORE::sprintf) return?
Is there any reason why not to go through a 'warning cycle'; where where it is warned that the prototype will change so it will be useful)?
Any anyone relying on the non-useful syntax\, should be warned to change code?
Language features DO change with a deprecation cycle...
Also\, in the case of sprintf(getformat()\, @args)...
if get format returns somethign else in 'list context'\, then wouldn't sprintf have thrown an error ? I.e. if the 1st arg is supposed to be a scalar\, 'getformat()' doesn't look like a simple scalar'\,
I.d. "push $foo\, blah"\, where "$foo" contains a ref to an array\, doesn't work. It has to be a type "@"\, Since it is supposed to be a scalar\, then a deprecation cycle could throw a warning if \$ isn't met for the 1st arg to sprintf...telling them to make sure it doesn't rely on 'wantarray'.
Since havin these two proglets return different results is nothing but confusing and would drive anyone in testing crazy:
perl -e ' sub x { wantarray ? "%d%s":"%5.2f%s"} print sprintf (x()\,2.7\,"\n"); ' 2.70 perl -e ' sub x { wantarray ? "%d%s":"%5.2f%s"} printf (x()\,2.7\,"\n"); ' 2
I mean you pass a format to sprintf\, and it prints out one thing\, but you pass it to printf\, and it prints out something else?
But this ONLY happens in perl (not in C or other langs supporting both)?
That really drives home the point about perl being unsupportable due to quirkiness.
On Mon\, Nov 7\, 2011 at 7:58 PM\, Linda Walsh \perl\-diddler@​tlinx\.org wrote:
Is there any reason why not to go through a 'warning cycle'; where where it is warned that the prototype will change so it will be useful)?
Any anyone relying on the non-useful syntax\, should be warned to change code?
Language features DO change with a deprecation cycle...
You may want to read Jesse's «Perl 5.16 and Beyond». The route you're proposing is not an option\, it's a simple as that. You can argue for different behavior under «use 5.16»\, though we'd need consensus for that\, something we don't seem to have yet\, and there's a looming contentious feature freeze I think.
I.d. "push $foo\, blah"\, where "$foo" contains a ref to an array\, doesn't work. Â It has to be a type "@"\, Since it is supposed to be a scalar\, then a deprecation cycle could throw a warning if \$ isn't met for the 1st arg to sprintf...telling them to make sure it doesn't rely on 'wantarray'.
Actually that works on 5.14 as an experimental feature\, it's the new '+' prototype ;-).
Since havin these two proglets return different results is nothing but confusing and would drive anyone in testing crazy:
It is inconsistent\, but one only has to learn it once. I wouldn't consider this one of our bigger issues.
Leon
Leon Timmermans via RT wrote:
On Mon\, Nov 7\, 2011 at 7:58 PM\, Linda Walsh \perl\-diddler@​tlinx\.org wrote:
Is there any reason why not to go through a 'warning cycle'; where where it is warned that the prototype will change so it will be useful)?
Any anyone relying on the non-useful syntax\, should be warned to change code?
Language features DO change with a deprecation cycle...
You may want to read Jesse's «Perl 5.16 and Beyond». The route you're proposing is not an option\, it's a simple as that. You can argue for different behavior under «use 5.16»\,
That would be fine...
though we'd need consensus for
that\, something we don't seem to have yet\,
The main sticking point being compatibility concerns with corner cases. If it was limited to 5.16 and beyond...then that shouldn't be a concern.
and there's a looming
contentious feature freeze I think.
I.d. "push $foo\, blah"\, where "$foo" contains a ref to an array\, doesn't work. It has to be a type "@"\, Since it is supposed to be a scalar\, then a deprecation cycle could throw a warning if \$ isn't met for the 1st arg to sprintf...telling them to make sure it doesn't rely on 'wantarray'.
Actually that works on 5.14 as an experimental feature\, it's the new '+' prototype ;-).
??? Eh? How's that work? or rather what works? The 'push' example?
Since havin these two proglets return different results is nothing but confusing and would drive anyone in testing crazy:
It is inconsistent\, but one only has to learn it once.
But 1 million have to learn it 1 million times. As was discussed\, there are many disparate workarounds for this 1 stupid inconsistency -- the writing of even 1 of them means too much time was wasted working around something that should never have existed in the first place.
I wouldn't consider this one of our bigger issues.
On that\, would have to agree. However\, on that: 1) in addressing issues look at cost to fix\, vs. benefit. cost to fix this is negligible\, benefit is high given the amount of time spent in workarounds for this design bug (may not be an implementation bug\, but designing perl's sprintf /printf functions to behave differently than every other sprintf/printf implement in regards to the format+arglists would definitely count as a design "oversight"... 2) It's always a good idea to pick off the low-hanging fruit first...it's easy. You know it's there\, so get it before it rots. and causes more problems.
If you think this is too great a change for 5.16\, then I'm fine with 5.18...but as you said\, it's a pretty minor change.
On Wed\, Oct 05\, 2011 at 05:20:17PM -0700\, Father Chrysostomos via RT wrote:
On Wed Oct 05 16:13:07 2011\, LeonT wrote:
On Wed\, Oct 5\, 2011 at 11:38 PM\, Brian Fraser \fraserbn@​gmail\.com wrote:
And it's not like prototypes haven't been changed before (to tchrist's chagrin\, e.g.
http://www.nntp.perl.org/group/perl.perl5.porters/2011/04/msg171420.html).
Most of the changes are completely backwards compatible
In fact\, most of the changes merely demonstrate how buggy prototype() has been in the past. Many of the prototypes it has returned (even in 5.14) do not represent how the function is actually parsed.
I think we're all agreeing\, and I'd like to add to it:
I think it's worth remembering that prototypes date from 5.003 The core parser dates from\, well\, Perl 1. Perl 5 attempted to regularise the parser.
Prototypes were added (if I understand it correctly) mainly to permit one to define functions that behaved like core builtins. The core's parser doesn't use prototypes to parse the builtins.
Prototypes are attempting to converge on the core parser\, not the other way. When prototypes have been changed\, I think it's usually without changes to the core parser - ie it's trying to better approximate what the core parser does.
Changing the "prototype" of a core builtin for the intent of changing behaviour doesn't actually mean changing the prototype. That's a derived property. It actually means changing the parser. Changing the parser is quite possible. But it's not just "a function in isolation".
So I think it's important to realise what level the change is actually at.
Nicholas Clark
Nicholas Clark via RT wrote:
On Wed\, Oct 05\, 2011 at 05:20:17PM -0700\, Father Chrysostomos via RT wrote: ...
I think we're all agreeing\, and I'd like to add to it: ... Prototypes were added (if I understand it correctly) mainly to permit one to define functions that behaved like core builtins. The core's parser doesn't use prototypes to parse the builtins. ... Changing the "prototype" of a core builtin for the intent of changing behaviour doesn't actually mean changing the prototype. That's a derived property. It actually means changing the parser. Changing the parser is quite possible. But it's not just "a function in isolation".
So I think it's important to realise what level the change is actually at.
Nicholas Clark
So question(s) then:
In something like push\, where $p is a pointer to an array\,
would it be a change to the prototype or the behavior to
have "push $p\,\" work\, w/o using "push @$p\,\
" (or
in some cases "push @{$p}\,\
"?
2nd (which started this) in sprintf\, to get the sprintf to behave like part after the optional IOh in printf\, i.e. printf [handle] (list)\, where 1st arg is interpreted as a format...
so instead of
sprintf \ (where generally:
list = \
listitem = \<listitem | "" >
)
we could just use
sprintf \
\, and have sprintf _behave_ the same\, but not
have the parser throw a cow^h^h^hwarning\, about a syntax problem?
^^ Would that be a change in the prototype\, or a change in the behavior?
(I guess it means what level of the interpreter one is talking about\, but conceptually\, I don't see behavior of either being changed\, just how they are parsed). If the were normal functions\, it would be a matter of changing sprint ($@) to (@)
and push from ($@)...
@ run time\, doesn't matter if you put '@' in front of '$p' or not\, if $p isn't a ref to an array...you still get 'not an array ref at xx'...
so execution\, I would think\, would catch things the same way as always.
in the case of sprintf (foobar()\,@_)\, I can think of no reason\, other to demonstrate 'kinky code' of having foobar return different things based on context of 'wantarray'\, despite the fact\, that this would break:
perl -E ' sub foobar { state $counter=0; my @answers=(3\,2\,42); unless (wantarray) {return !@answers?"":"%d".("\, %d" x $#answers)."\n"} else { return $answers[$counter++] } } print sprintf foobar()\,foobar()\,foobar()\,foobar();' 3\, 2\, 42
despite being able to use a greater than or equally perverse:
perl -E ' sub foobar { state $counter=0; my @answers=(undef\,3\,2\,42); $answers[0] = !$#answers ? "" : "%d" . "\, %d" x ($#answers-1) . "\n"; $answers[$counter++]; } print sprintf foobar()\,foobar()\,foobar()\,foobar();' 3\, 2\, 42
Neither of which would belong in any book on programming style and clarity. So how likely is it\, that the first would be used and be important enough not to fix the wart#2?
On Fri Nov 11 15:33:53 2011\, LAWalsh wrote:
So how likely is it\, that the first would be used and be important enough not to fix the wart#2?
I donât think anyone with the expertise to do this actually agrees with you; hence it is not likely. I happen to be one of those disagreeable individuals\, so let me explain my reasoning:
If you look at the big picture\, it is actually printf that is the odd one out. Almost every Perl operator that takes some scalar argument in a list of arguments evaluates it in scalar context.
Changing sprintf under a version declaration doesnât seem worth it to me. Itâs such a tiny\, subtle change\, that it may trip up more people than it helps.
With the new CORE:: subs it starts getting harder to change the prototype based on a version declaration. Should
my $sprintf = \&CORE::sprintf; prototype($sprintf)
return different values depending on the version declaration?
But I think your suggestion is unnecessary\, precisely because CORE:: subs allow you to change the prototypes easily:
use subs "sprintf"; # override built-in sub sprintf(@) { goto &CORE::sprintf }
And to demonstrate:
$ perl5.15.4 -le 'use subs "sprintf"; sub sprintf(@) { goto &CORE::sprintf } print sprintf @{["[%s]"\, "jiggles"]}' [jiggles]
If we ever get to making all keywords overridable\, someone could write a module to turn off all prototypes.
--
Father Chrysostomos
Father Chrysostomos via RT wrote:
On Fri Nov 11 15:33:53 2011\, LAWalsh wrote:
So how likely is it\, that the first would be used and be important enough not to fix the wart#2?
I donât think anyone with the expertise to do this actually agrees with you; hence it is not likely.
Are you saying that if someone with the expertise to do this does it\, then it would go in? I.e. if a patch were provided\, there'd be no *blocking* resistance to fixing it?
Changing sprintf under a version declaration doesnât seem worth it to me. Itâs such a tiny\, subtle change\, that it may trip up more people than it helps.
=== Conversely\, anyone who looks at perl and knows C\, would know that the args to one are the same as to the other with the exception of the need for an output var to sprintf\, (which perl handles by putting on the left side of an assignment).
That why such a tiny subtle breakage from the standard expectations concerning sprintf and printf\, is so critical to address.
It's a matter of how perl is perceived -- is a (in your 'big picture'\, just ANOTHER one of the many little 'quirks' that add to the (often\, overblown) perception\, that Perl is difficult to use/learn/maintain?
Polish is important. It's NOT to most engineers. But it's part of creating impressions of a product that ultimately make or break it. This is no game changer by itself. It's nothing\, but if every little 'nothing'\, could be addressed\, you'd have a polished product\, vs. something that is "just" a flexible useful tool.
And to demonstrate:
$ perl5.15.4 -le 'use subs "sprintf"; sub sprintf(@) { goto &CORE::sprintf } print sprintf @{["[%s]"\, "jiggles"]}' [jiggles]
In demonstrating your example you broke basic perl development practices. You didn't turn on warnings and strict.
Will your program work if you turn on standard development switches?
-l
Migrated from rt.perl.org#100190 (status was 'rejected')
Searchable as RT100190$