Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 527 forks source link

perlsub manpage 1) has a missing ';' 2) return *READER -> return *READER{IO}? #5160

Closed p5pRT closed 21 years ago

p5pRT commented 22 years ago

Migrated from rt.perl.org#8711 (status was 'resolved')

Searchable as RT8711$

p5pRT commented 22 years ago

From tagunov@motor.ru

This is a bug report for perl from "Anton Tagunov" \tagunov@​motor\.ru\, generated with the help of perlbug 1.33 running under perl v5.6.1.


Hi!

The perlbug manpage has the following sample​:

--   sub ioqueue {   local (*READER\, *WRITER); # not my!   pipe (READER\, WRITER); or die "pipe​: $!";   return (*READER\, *WRITER);   }   ($head\, $tail) = ioqueue();
--

1) Apparently\, it should be   pipe (READER\, WRITER) or die "pipe​: $!"; without the semicolon

2) Maybe put it   return (*READER{IO}\, *WRITER{IO}); ? At least print $head\,' '\,$tail\,"\n"; would prints something much more reasonalbe after the sample this way :-)

The only doubt I have is whether it would work for older perls and do the manpages have an aim to provide samples that run both on old and new perls.

Regards\, Anton



Flags​:   category=docs   severity=low


Site configuration information for perl v5.6.1​:

Configured by anthony at Wed Oct 31 20​:29​:27 2001.

Summary of my perl5 (revision 5 version 6 subversion 1) configuration​:   Platform​:   osname=MSWin32\, osvers=4.0\, archname=MSWin32-x86-multi-thread   uname=''   config_args='undef'   hint=recommended\, useposix=true\, d_sigaction=undef   usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define   useperlio=undef d_sfio=undef uselargefiles=undef usesocks=undef   use64bitint=undef use64bitall=undef uselongdouble=undef   Compiler​:   cc='cl'\, ccflags ='-nologo -O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX'\,   optimize='-O1 -MD -DNDEBUG'\,   cppflags='-DWIN32'   ccversion=''\, gccversion=''\, gccosandvers=''   intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234   d_longlong=undef\, longlongsize=8\, d_longdbl=define\, longdblsize=10   ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=4   alignbytes=8\, usemymalloc=n\, prototype=define   Linker and Libraries​:   ld='link'\, ldflags ='-nologo -nodefaultlib -release -libpath​:"C​:\usr\local\lib\CORE" -machine​:x86'   libpth="E​:\apps\vc98\sdk.1\Lib\." "E​:\apps\ibm\db2p\LIB" "C​:\usr\local\lib\CORE"   libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib   perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib   libc=msvcrt.lib\, so=dll\, useshrplib=yes\, libperl=perl56.lib   Dynamic Linking​:   dlsrc=dl_win32.xs\, dlext=dll\, d_dlsymun=undef\, ccdlflags=' '   cccdlflags=' '\, lddlflags='-dll -nologo -nodefaultlib -release -libpath​:"C​:\usr\local\lib\CORE" -machine​:x86'

Locally applied patches​:   ACTIVEPERL_LOCAL_PATCHES_ENTRY


@​INC for perl v5.6.1​:   C​:/usr/local/lib   C​:/usr/local/site/lib   .


Environment for perl v5.6.1​:   HOME=C​:\   LANG (unset)   LANGUAGE (unset)   LC_ALL=EN_US   LD_LIBRARY_PATH (unset)   LOGDIR (unset)   PATH=E​:\apps\ibm\vaj\eab\bin;C​:\usr\local\bin\;e​:\Program Files\ibm\gsk5\lib;E​:\APPS\ROSE\RATION~1\NUTCROOT\bin;E​:\APPS\ROSE\RATION~1\NUTCROOT\bin\x11;E​:\APPS\ROSE\RATION~1\NUTCROOT\mksnt;e​:\java\sun\java131\bin;e​:\apps\vbroker\jre\Bin;e​:\apps\vbroker\Bin;C​:\WINNT\system32;C​:\WINNT;c​:\program files\util;E​:\apps\CacheSys\Bin;C​:\Program Files\rksupport;C​:\WINNT\ton\bin;E​:\apps\rose\common;E​:\apps\rose\Rational Test;E​:\apps\borland\delphi\Bin;E​:\apps\borland\delphi\Projects\Bpl;E​:\apps\ibm\IBM\IMNNQ;E​:\apps\ibm\db2p\BIN;E​:\apps\ibm\db2p\FUNCTION;E​:\apps\ibm\db2p\SAMPLES\REPL;E​:\apps\ibm\db2p\HELP;e​:\apps\ibm\websphere\bin   PERL_BADLANG (unset)   SHELL (unset)

p5pRT commented 22 years ago

From [Unknown Contact. See original ticket]

Hello Yitzchak!

Just finished trying to convert you sacred knowledge to pod documentation :-) Please feel free to correct!

Inline Patch ```diff --- pod/perldata.pod.orig Mon Mar 4 12:18:27 2002 +++ pod/perldata.pod Wed Mar 13 05:34:20 2002 @@ -729,6 +729,33 @@ return *FH; } $fh = newopen('/etc/passwd'); + while( <$fh> ){ ... } + +If a typeglob C<*FH> has been localized (like in this example), +assigning it or a hard reference to it (C<\*FH>) to a scalar that +is available in some fashion after leaving the localization scope +(including but not limited to returning a value from a C +or a function) is called I. In general, any C or +C thing that has a reference to it I away somewhere +doesn't actually get destroyed. The C restores the symbol +table C<*FH> at the end of the sub, but you are left with a scalar +that has a typeglob or a typeglob reference assigned to it, this +typeglob/typeglob reference remaining associated with the former +local version of C<*FH>. This scalar is dereferencable according +to the regular L: + + my $r; + our $v='outer'; + {local *v; $v='inner'; $r=*v;} + print $$r; #prints 'inner' + +Such scalar is a valid C argument to +L (as in the +example above) just because a C +argument to L, L, +L, L is a +legitimate use for a scalar that has been assigned with a +typeglob or a typeglob reference. Now that we have the C<*foo{THING}> notation, typeglobs aren't used as much for filehandle manipulations, although they're still needed to pass brand --end of patch--- ```

AT>And a silly question to show me as a green novice, not a hacker: AT>how can a typeglob be returned if it refers to a localized variable?

YST> In general\, any local or my thing that has a reference to it stashed YST> away somewhere (or\, in the case of GLOBs\, is returned or stored in YST> some scalar that is available in some fashion after leaving the scope) YST> doesn't actually get destroyed. The local restores the symbol table YST> *READER and *WRITER at the end of the sub but you are left with a copy YST> of the local version. (But for GLOBs it has a special FAKE flag that YST> makes it fail in some circumstances--I forget where). In general\, you YST> should use Symbol​::gensym now instead of local\, and globrefs instead YST> of actual globs.

Regards\, Anton

p5pRT commented 22 years ago

From [Unknown Contact. See original ticket]

Hello Yitzchak!

Going further to convert you mails to docs! If you think that I have been bold\, well.. I was actually thinking about slapping your name and mail under this :) but at the last moment I reconsidered and have left that at you discretion ;-)

This patch also does some s/both/only/g.. Fill free to cut that out.. It was my impression of a novice that with 'only' it would sound more reasonable\, then with 'both'\, but probably I have broken the author's intention..

Inline Patch ```diff --- pod/perlref.pod.orig Wed Mar 13 05:56:24 2002 +++ pod/perlref.pod Wed Mar 13 06:14:02 2002 @@ -263,7 +263,7 @@ below, there's no risk of that happening. splutter(*STDOUT); # pass the whole glob - splutter(*STDOUT{IO}); # pass both file and dir handles + splutter(*STDOUT{IO}); # pass only file and dir handles sub splutter { my $fh = shift; @@ -271,12 +271,28 @@ } $rec = get_rec(*STDIN); # pass the whole glob - $rec = get_rec(*STDIN{IO}); # pass both file and dir handles + $rec = get_rec(*STDIN{IO}); # pass only file and dir handles sub get_rec { my $fh = shift; return scalar <$fh>; } + + +While there's a plan to largely get away from using +globs by 5.9, currently the iorefs (what you get from C<*FOO{IO}>) +are recommended to be used with caution: they have not been used by +enough people to shake the bugs out. Namely there's a known bug +with C<$.> not being set when reading from an ioref; also they +I<*look*> like objects blessed into C (unless you've +previously used C) but there is no provision for +automatically loading C if you try to use them as +objects; even if there was some such provision, the C +hack means you are at the mercy of any modules you use -- if they +happen to use C, you won't get C methods +available on the object). Naturally, users are encouraged to +experiment with iorefs and +L :-). =back ```

AT>- return (READER, WRITER); AT>+ return (*READER{IO}\, *WRITER{IO}); AT> AT>Is that okay? Is that smth to recommend to people?

YST> I wouldn't recommend using iorefs (what you get from *FOO{IO}) since I YST> don't feel they have been used by enough people to shake the bugs out YST> (play with readline *STDIN{IO} and print $.\, for instance; also they YST> *look* like objects blessed into IO​::Handle (unless you've previously YST> used FileHandle) but there is no provision for automatically loading YST> IO​::Handle if you try to use them as objects; even if there was some YST> such provision\, the FileHandle hack means you are at the mercy of any YST> modules you use--if they happen to use FileHandle\, you won't get YST> IO​::Handle methods available on the object).

YST> I had hoped to stir up some interest in making IO thingies more YST> accessible and dependable and get away from using globs as much as YST> possible for 5.9.

- Anton

p5pRT commented 22 years ago

From @mjdominus

+If a typeglob C\<*FH> has been localized (like in this example)\, +assigning it or a hard reference to it (C\<\*FH>) to a scalar that +is available in some fashion after leaving the localization scope +(including but not limited to returning a value from a C\<do{}> +or a function) is called I\.

This is not really correct. 'stash' is a colloquial English verb that means to hide away or to store for later. Its use here is not special jargon.

In general\, any C\ or +C\ thing that has a reference to it I\ away somewhere +doesn't actually get destroyed.

This is just a special case of the rule that says that data is not destroyed as long as there is a possibility of using it again.

It seems to me that it would be better to chop out this entire section. the { local *F; return *F } trick is of limited usefulness now that "open my $fh\, ..." works.

p5pRT commented 22 years ago

From [Unknown Contact. See original ticket]

Hello Mark-Jason!

Glad you have answered\, double glad so soon! :-)

+If a typeglob C\<*FH> has been localized (like in this example)\, +assigning it or a hard reference to it (C\<\*FH>) to a scalar that +is available in some fashion after leaving the localization scope +(including but not limited to returning a value from a C\<do{}> +or a function) is called I\.

MJD> This is not really correct. 'stash' is a colloquial English verb that MJD> means to hide away or to store for later. Its use here is not special MJD> jargon.

Yes\, I have looked up my e-dictionary before writing this :-) The reason I have italicized it is that

perl -MDevel​::Peek -we "Dump(*STDIN);"

prints out

SV = PVGV(0x15e6bec) at 0x15dba54   ...   GvSTASH = 0x15d43e8 "main"   ...   EGV = 0x15dba54 "STDIN"

So I have concluded that STASH is either a name of an internal function or field in datastructure.. The very little I know about Perl internals\, from this and from Yitzchak's mail I concluded that it has a special meaning in Perl. Doesn't it? Well\, at least doing $v=*FOO does not change the REFCNT of FOO\, but still *FOO values survive leaving the scope of the local directive.. I have taken 'stash' to mean exactly this. Have I bee wrong?

In general\, any C\ or +C\ thing that has a reference to it I\ away somewhere +doesn't actually get destroyed.

MJD> This is just a special case of the rule that says that data is not MJD> destroyed as long as there is a possibility of using it again.

I can always refer to Yitzchak's original mail.. But I'm so grateful to him for clearing things out for me that I would give my arguments first​:

Seeing it with eyes of a freshman (I have been Perl-ing only for 3 weeks now\, so my eyes are pretty fresh at it ;-) the rule that data is not destroyed until its REFCNT is above zero is almost intuitive. But that doing $v=*FOO prevents some data from vanishing\, without changing REFCNT of any of FOO components\, with print $v printing "*main​::FOO" and print $v eq "*main​::FOO" printing 1.. Ufff... this sounds like a black-dark-deep Vodoo magic!

I'm so grateful to Yitzchak for helping me out... You know what he did? He just gave it name. "Stashing". He has just told me that. And since something has been given a name it does not scare that much\, that's human nature :-) And his remark about "stashing" out references\, all being two-purposed (one meaning is using stash as a synonym to 'hide' and then this sentence is speaking about the \ references too\, the second meaning treating "stashing" as a special case of keeping data alive without increasing CNTREF) has helped me out a great deal. I think other new-bies may have feelings similar to mine... So I very very strongly would ask you to keep this fragment.

MJD> It seems to me that it would be better to chop out this entire MJD> section. Please\, if it can be rephrased\, rewritten or anything\, but with preserving the meaning?

MJD> the { local *F; return *F } trick is of limited usefulness MJD> now that "open my $fh\, ..." works. Oh\, even if goes for good (and that will probably good :-) from the core perl distribution\, I'm afraid that a number of third party scripts will be long available.. Is that an argument? ;-)

- Anton

p5pRT commented 22 years ago

From [Unknown Contact. See original ticket]

Anton Tagunov wrote​:

Hello Mark-Jason!

Glad you have answered\, double glad so soon! :-)

+If a typeglob C\<*FH> has been localized (like in this example)\, +assigning it or a hard reference to it (C\<\*FH>) to a scalar that +is available in some fashion after leaving the localization scope +(including but not limited to returning a value from a C\<do{}> +or a function) is called I\.

MJD> This is not really correct. 'stash' is a colloquial English verb MJD> that means to hide away or to store for later. Its use here is MJD> not special jargon.

Yes\, I have looked up my e-dictionary before writing this :-) The reason I have italicized it is that

perl -MDevel​::Peek -we "Dump(*STDIN);"

prints out

SV = PVGV(0x15e6bec) at 0x15dba54 ... GvSTASH = 0x15d43e8 "main" ... EGV = 0x15dba54 "STDIN"

So I have concluded that STASH is either a name of an internal function or field in datastructure..

STASH stands for Symbol Table hASH.... It probably should have been something like "GvPACKAGE"\, but too much code uses it as it is for us to change it... so we're stuck with that name.

-- print reverse( "\,rekcah"\, " lreP"\, " rehtona"\, " tsuJ" )."\n";

p5pRT commented 22 years ago

From [Unknown Contact. See original ticket]

Hello Mark-Jason!

MJD> In Perl\, the noun "stash" refers to a symbol table hash Got it :)

AT> Seeing it with eyes of a freshman ... AT> the rule that data is not destroyed until its REFCNT is above zero AT> is almost intuitive. But that doing $v=*FOO prevents some data AT> from vanishing\,

MJD> There is nothing unusual about this. The = operator copies data. MJD> The situation is the same as if you did

MJD> my $r; MJD> our $w=1; MJD> {local $w; $w=4; $r=$w;} MJD> print $r; #prints 4

#Hmmm\, consider my $r; our $w='outer'; { local *w; $w='inner'; $r=*w; $w='new inner'; } print $$r; #prints 'new inner'! BLACK VODOOOOO AGAIN! :)

So $r=*w does not affect the REFCNT of $w but $r follows the value of $w\, pretty much like a symbolic reference does\, but then unlike the symbolic reference it prevents $w from vanishing at the end of local scope.

Isn't $r=*w something very special and unlike - $r=\$w - $r='w' - $r=$w ?

Isn't it good to try to better document it?

Isn't it falling general rules one would naively expect?

(For example\, I was expecting at my first reading of the manpages that $r=*w or *r=*w would make $r follow the actual value of $w\, that is to print 'outer' in the example above. At my second reading I just was scared and not understanding anything)

BTW\, am I right that *r=*w is sloppily equivalent to $r=*w; @​r=*w; %r=*w; etc ?

MJD> It seems to me that it would be better to chop out this entire MJD> section. the { local *F; return *F } trick is of limited usefulness MJD> now that "open my $fh\, ..." works.

Better move it it to a new perloldstyle.pod? I believe that knowledge should be evangelized as much as possible and what we're speaking about is knowledge\, probably necessary to understand/ debug existing scripts (and I bet even helpful in understanding samples in the Camel book :)!

- Anton

p5pRT commented 22 years ago

From [Unknown Contact. See original ticket]

Mama mia! Finally got the typeglobs (approximately :)

Sorry I have been questioning here\, Should have used newsgroups :-/

Please disregard my prev mails on this

-Anton

p5pRT commented 21 years ago

From @cwest

Extra semicolon but fixed and shipped with Perl 5.8.0.

p5pRT commented 21 years ago

@cwest - Status changed from 'open' to 'resolved'