How to use select (select(2)) in Perl?

U

Uri Guttman

KM> Gee, a voice of reason. You obviously don't belong in this
KM> newsgroup. The very idea that the paragraph you wrote above could
KM> be considered controversial is proof that this newsgroup really is
KM> populated by lunatics.

that doesn't change the fact that you are a maroon. just reading about
select which refers to the vec function and then not reading about vec
is proof. you hate perl so why do you even bother? we don't need your
<SARCASM>sanity</SARCASM> here.

uri
 
B

Ben Morrow

Bernie Cosell said:
} Ummm.... as far as I can see it's perfectly clear. 'use vars
} qw/$foo/;' (called from package 'My::pack') chops the '$' off '$foo',
} makes sure it's fully qualified, does some error checking and then
} executes
}
} *My::pack::foo = \$My::pack::foo;

Actually, that leaves something out -- I think you have to be in a
different package assigning into the original or something like that. I
tried to do a in-line use-vars and there was some [undocumented]
packageness requirement [if I remember right] or else the * = \ assignment
didn't turn off the error...

Yes, OK, you are right. I had forgotten that. The assignment has to
occur in a different package from that which you are assigning into.
} . The reason why this stops the error is not explained anywhere in the
} perl docs, I grant you, but it isn't hard to figure out.

Oh? Consider:

use strict ;

*main::c = \$main::c;
$c = 4 ;

Will that compile and run or not?

You have missed the most important part of my explanation: as the
*foo=\$foo is happening in a BEGIN block (or rather a 'use'
statement), it happens at *compile* *time*, and thus its effects are
present for the rest of the compilation.

Consider:

use strict;
BEGIN {
package Foo;
*main::c = \$main::c
}
$c = 4;

The fact that this incantation is what is required to turn off the
error is indeed undocumented, but that simply means *you do not need
to know it*. The documented means for avoiding strict warnings are my,
our and use vars.

Do you understand the meaning of 'modularity' with respect to software
design?

Ben
 
B

Ben Morrow

Bernie Cosell said:
} Yes, OK, you are right. I had forgotten that. The assignment has to
} occur in a different package from that which you are assigning into.

That was my point: WHERE EXACTLY is that documented?? How did you learn
that little tidbit to have forgotten it???

It is not documented. It is perl internals. Do you know what all the
various values of $^H do? Where are they documented? They aren't: they
are private between perl and the core pragmas, and subject to change
at any time without notice. The same applies to this: p5p are
perfectly entitled to change this behaviour at any time, without
warning, as long as use vars continues to work.

This is what I mean by 'modularity'. use vars is *not* a library: it
is part of the language. The same goes for IO::*.

As for where I learnt it, it's kinda obvious from the
message. "Variable "$x" is not imported": hence, if it had been
imported, it would have been OK; what is the difference between
importing a variable and what you wrote? That an import occurs in the
package the variable is imported from.
I haven't a clue *WHY* perl requires that, or why *HOW* you create the
symtab entry makes a difference to the 'strict' machinery, but a while back
[when I needed to write my own version of 'use vars'] it was VERY
frustrating not being able to find that bit of lore. You're trying to
argue that it is a *good*thing* to leave stuff like that
undocumented?

Yes, I am, because it is subject to change. If p5p change that
behaviour, it is likely your use vars will cease to work. [The fact
that the behaviour probably can't be changed for other reasons is
beside the point...] Why did you need to rewrite use vars anyway,
especially in such a way that it was doing the importing from the
receiving package?
} Do you understand the meaning of 'modularity' with respect to software
} design?

Sure do -- and it has nothing to do with what's going on here. Same thing
with GetOpt - I use it when it fits what my application needs, but I mess
with ARGV directly when I have to.

Right. ARGV is documented, so feel free to do what you like with it.
I don't understand your point.

Things that are undocumented are undocumented because they are not for
public use. Indeed, plenty of things are documented, but should not be
used because they are private to perl, for instance the SvIOKp flag on
a scalar.
IMO, only the most myopic and narrow-minded of folk [mostly brainwashed
from having taken too many undergraduate "object oriented programming"
classes, I suspect]

Myopic I may be (-10 and -12 dioptres, with astigmatism :), but I am
not narrow-minded; and I have *certainly* never taken an undergraduate
OOP class.

Ben
 
T

Tassilo v. Parseval

Also sprach Bernie Cosell:
I notice that you skipped over the comment about your patronizing Lucy
science lecture: indeed, I had done that same analysis (which is hardly
difficult) and STILL couldn't figure out why use vars worked but the
version I needed wouldn't.

} > } Yes, OK, you are right. I had forgotten that. The assignment has to
} > } occur in a different package from that which you are assigning into.
} >
} > That was my point: WHERE EXACTLY is that documented?? How did you learn
} > that little tidbit to have forgotten it???
}
} It is not documented. It is perl internals.

Perhaps -- odd argument, I think. What *IS* someone supposed to do if 'use
vars' doesn't do quite what they want? Is that really some deep secret
part of the system in your view? [and it still leaves me a bit mystified
as to WHY the simple global-assignment doesn't work, but the
global-assignment *across* a package does. that means that somehow when
you do "$pack::var" perl does something a tiny bit different if you're *in*
package 'pack' or in some other package... Odd...:eek:)]

There is always a moment in which you wish that the core of the language
was different from the way it is. If you find the 'vars' pragma
unsuitable for your task, then it's your privilege to look at its
internals and come up with something more suitable.

You have to keep this in mind: the people who designed and made Perl are
not infallible. When they did 'vars', they had something in mind and
honstly believed that it would be sufficient and cover all cases. It's
tough luck that it maybe doesn't quite achieve this degree of
perfection.

The assumption that the innards of 'vars' are undocumented due to the
developers' malice is wrong. There just didn't happen to be someone
around who thought it would be necessary or worth the pain to document
it. If you know how and why it works and you are willing to add the
missing piece of explanation to, say, perlref.pod, I am sure the porters
wouldn't reject such an addition.

As far as the development of Perl is concerned, there has always been
one important rule: Either complain and whine, or fix it and make the
world a better place.

Tassilo
 
B

Ben Morrow

Bernie Cosell said:
I notice that you skipped over the comment about your patronizing Lucy
science lecture: indeed, I had done that same analysis (which is hardly
difficult) and STILL couldn't figure out why use vars worked but the
version I needed wouldn't.

This is mostly because the term 'Lucy science lecture' is not one I am
familiar with: I take it refers to the fact that my analysis, although
perhaps convincing, was incorrect? I apologise. As I said, I don't
think the final step was that hard to figure out, either.

[and it still leaves me a bit mystified
as to WHY the simple global-assignment doesn't work, but the
global-assignment *across* a package does. that means that somehow when
you do "$pack::var" perl does something a tiny bit different if you're *in*
package 'pack' or in some other package... Odd...:eek:)]

Think about it. Use strict has to shout at you about using a global
unless

1. you have declared it with our,
2. it is fully qualified, or
3. it has been exported by some module.

This odd behaviour covers case 3, of which use vars is a special case.
} This is what I mean by 'modularity'. use vars is *not* a library: it
} is part of the language. The same goes for IO::*.

Gad, I hope you won't be part of the core implementation group -- I can
only assume that you'll argue that the documentation for 'open' should be
removed, since IO::File is "part of the language".

I don't think that documentation should ever be removed, unless it is
confusing and does more harm than good. I have also never used
IO::File, and (since the development of lexical FHs) can't see any
reason why I ever should.
} > I don't understand your point.
}
} Things that are undocumented are undocumented because they are not for
} public use....

You think that 'select()' shouldn't be for public use? None of the
available docs even hint at such a thing...

About the only sensible point in this discussion... yes, I was
suggesting that direct use of select() should be deprecated in favour
of IO::Select. I would say the same of IO::Socket and the low-level
socket functions.
} Myopic I may be (-10 and -12 dioptres, with astigmatism :), but I am
} not narrow-minded; and I have *certainly* never taken an undergraduate
} OOP class.

Well, sounds like it on two fronts:

1) you're apparently an advocate that there should only be ONE way to do
things. IO::File is there, and the direct use of 'open' is now, in your
world, deprecated. [oh, sorry, you were just making the parallel arg about
IO:Select and select()..:eek:)]

There is an important difference between IO::Select and IO::File,
which is that IO::Select actually does something useful. As you found
out, doing a low-level select call yourself is fiddly and requires
some rather cryptic and unintuitive, not to mention C-like, operations
to construct the arguments and get the data back out. IO::Select is a
very thin wraper around that, that provides a Perlish interface. I'd
be willing to bet that if perl hadn't had select in the first place,
and IO::Select where to be implemented now as an extension, the
interface would be much as it is now; perhaps with a note in the
documentation saying 'the underlying select(2) call is available as
IO::Select::sysselect'.

IO::File, OTOH, gives you nothing over a simple open: indeed, I find

my $fh = IO::File->new("< file");

substantially harder to read than

open my $FH, "< file";

..
2) the recommendation at hand, to use IO::Select, basically forces a
[relatively] behemoth OO package

!!! hardly. Have you read the source? I can't be bothered to benchmark
it, but I bet if you did it would be no slower than doing all the
vec() stuff by hand.
down our throats, even if we happen not to want to be doing OO right
there -- again, the usual stance of the pedant, who believes that OO
is the only-true-right way to accomplish any task.

This is mudslinging, so I will only say that until I found Perl's OO,
which lets you do OO when it's convenient and not when it's not, I
would have said that OO was not something I would want to use.
It is one thing to carp about $^H, which is clearly documented:

$^H WARNING: This variable is strictly for internal
use only. Its availability, behavior, and con­
tents are subject to change without notice.

but in IO::Select, it just says:

The "IO::Select" package implements an object approach to
the system "select" function call.

Which hardly sounds like "THIS IS THE ONLY APPROVED WAY TO DO SELECT IN
PERL", does it?

No. What I was suggesting was that, since the documentation for select
is (apparently) cryptic and inadequate to enable anyone without
intimate knowledge of perl internals to use it, it be changed to say
something more along those lines. Then perhaps we wouldn't get muppets
here asking questions whose answers require nothing more than a small
amount of thought.

Ben
 
B

Ben Morrow

Bernie Cosell said:
Actually, I don't even know the true thing that makes use-vars work. Is it
that the coloned-global assignment must be to a package *other* than the
one you're in?

Yes, exactly that.
It is such an abstruse thing, I'm not sure even *where* you'd
document it [other than in vars.pm!] -- maybe someplace in the
'strict' documentation if anywhere]. BUT: I wouldn't mind a little
intution-helping explanation of how [if not why] a cross-package
fully-qualified assign does something different than a same-package
fully-qualified assign. [with a double lurking-question here: are there
any OTHER odd/hidden effects of cross vs self FQ-assigns, and are there any
other sorts-of-operations that can have a similar effect for 'strict'
*other* than a cross-package FQ assign]

The only real explanation is in sv.c:

/* copy sstr into dstr (I've only left in the relevant bits :) */
void
Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
{
register U32 sflags;
register int dtype;
register int stype;

sflags = SvFLAGS(sstr);
if (sflags & SVf_ROK) { /* if the source is a ref */

if (dtype >= SVt_PV) {
if (dtype == SVt_PVGV) { /* and the dest is a glob */

SV *sref = SvREFCNT_inc(SvRV(sstr));
/* sref is the deref of sstr: what sstr pointed at */

switch (SvTYPE(sref)) {
/* snip lots of cases, leaving only 'ordinary' scalars */
default:
GvSV(dstr) = sref; /* make the assignment */

if (!GvIMPORTED_SV(dstr)
/* if the dest isn't marked as imported yet */

&& CopSTASH_ne(PL_curcop, GvSTASH(dstr)))
/* and the current pkg is different from
* the dest pkg (a pkg is called a STASH
* in the perl core) */
{
GvIMPORTED_SV_on(dstr); /* mark it as imported */
}
break;
}
}
}
}
}

This GvIMPORTED_SV flag is what strict checks for when it finds an
unqualified global. There are equivalent flags for the hash, array and
code slots in the glob.

Ben
 
B

Ben Morrow

Bernie Cosell said:
} Use strict has to shout at you about using a global
} unless
}
} 1. you have declared it with our,
} 2. it is fully qualified, or
} 3. it has been exported by some module.

Would you care to say where you got these three rules from?

Err.... I can't remember :). I'm sure I read them somewhere, along
with an statement about glob assignment not working into the current
package... I would suspect the Camel, but I can't find it anywhere
with a quick check.
Perhaps we could agree that the ONLY real change in the documentation
that'd finesse this tempest in a teacup would be to add your third rule to
the first bit of documentation... something like

declared beforehand using "our",
explicitly qualified to say which package the global
variable is in (using "::"), or exported into the current
package from some other package.

If there's no disagreement about the above [and it is actually correct],
I'll be happy to put that tiny change into perldiag. [although I don't
think I'm a 'registered' guy so I'd have to find out how to go about doing
that...]

I'd certainly agree with that.
} > Well, sounds like it on two fronts:
} >
} > 1) you're apparently an advocate that there should only be ONE way to do
} > things. IO::File is there, and the direct use of 'open' is now, in your
} > world, deprecated. [oh, sorry, you were just making the parallel arg about
} > IO:Select and select()..:eek:)]
}
}
} There is an important difference between IO::Select and IO::File,
} which is that IO::Select actually does something useful. As you found
} out, doing a low-level select call yourself is fiddly and requires
} some rather cryptic and unintuitive, not to mention C-like, operations
} to construct the arguments and get the data back out.

Speak for yourself at how fiddly an "unintuitive" it is. And you think the
rules for ">" "+>" "&" "|" etc aren't 'fiddly' and C/unix-like with
open?

open isn't at all C-like; shell-like, rather. By 'fiddly' I mean that
performing a select operation manually requires one statement per FH
to build the args, one for the select and one per FH to test the
output. IO::Select reduces that to two statements: one to build the
object and one to perform the test. (I would actually like a select()
function that simply takes three lists of FHs and a timeout, and
returns three lists of FHs. This seems the obvious Perl
implementation, to me.)
The difference is only that you don't understand 'select()' and aren't
comfortable with the vec stuff, and perhaps others are

I am perfectly happy with select in C. One of the reasons I would
choose to write Perl rather than C is because things are not done like
that in Perl: there is a general provision of a slightly higher-level,
more intuitive (to a Perl programmer) interface for nearly
everything. You have said you don't like Perl, which is fine: if you'd
rather do all the little bits yourself the go ahead and write C. I
would suggest that most people who prefer Perl to C would prefer
IO::Select over a raw select call.
} ... IO::Select is a
} very thin wraper around that, that provides a Perlish interface.

No, not "perlish" but "perl object-oriented". And not so paper thin -- it
pulls in more of the IO:: machinery [IO::Handle, at the least].

Err... nope.
Not a huge
amount of stuff, I meant "relatively" behemoth, because you have the [at
least two] packages you don't otherwise need,

A 'package' is nothing. No overhead whatsoever. IO::Select pulls in
Exporter (which has had all the complicated bits ripped out into
Exporter::Heavy, so you don't get them if you don't need them),
strict, warnings and vars.
and the OO overhead on all the operations,

This is the only overhead on top of performing the vec()s yourself. As
I said, I haven't benchmarked it; but I'd be willing to bet it's
completely trivial.
} ... I'd
} be willing to bet that if perl hadn't had select in the first place,
} and IO::Select where to be implemented now as an extension, the
} interface would be much as it is now; perhaps with a note in the
} documentation saying 'the underlying select(2) call is available as
} IO::Select::sysselect'.

I don't know: is there *ANY* other facility in Perl that is *ONLY*
available through an OO interface??

Yup. Lots of them. Tied variables, for a start; then there're all the
Net::* modules for the various network protocols, CGI (the function
interface is a wrapper round the OO, rather than the other way round),
'most anything that needs some sort of state. It's simply the natural
way to do things like that in Perl.

Perl5 is a very different language from perl4.

Ben
 
T

Tassilo v. Parseval

Also sprach Ben Morrow:
It is such an abstruse thing, I'm not sure even *where* you'd
document it [other than in vars.pm!] -- maybe someplace in the
'strict' documentation if anywhere]. BUT: I wouldn't mind a little
intution-helping explanation of how [if not why] a cross-package
fully-qualified assign does something different than a same-package
fully-qualified assign. [with a double lurking-question here: are there
any OTHER odd/hidden effects of cross vs self FQ-assigns, and are there any
other sorts-of-operations that can have a similar effect for 'strict'
*other* than a cross-package FQ assign]

The only real explanation is in sv.c:

/* copy sstr into dstr (I've only left in the relevant bits :) */
void
Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
{
[...]

if (!GvIMPORTED_SV(dstr)
/* if the dest isn't marked as imported yet */

&& CopSTASH_ne(PL_curcop, GvSTASH(dstr)))
/* and the current pkg is different from
* the dest pkg (a pkg is called a STASH
* in the perl core) */
{
GvIMPORTED_SV_on(dstr); /* mark it as imported */
}
break;
}
}
}
}
}

This GvIMPORTED_SV flag is what strict checks for when it finds an
unqualified global. There are equivalent flags for the hash, array and
code slots in the glob.

According to Perl_gv_fetchpv() only variables with type SVt_(PV|AV|HV)
need to be imported. This is totally consistent with the way you call
functions. They never have to be package-qualified or exported in a
funny way over package-boundaries.

Tassilo
 
B

Ben Morrow

Also sprach Ben Morrow:

According to Perl_gv_fetchpv() only variables with type SVt_(PV|AV|HV)
need to be imported. This is totally consistent with the way you call
functions. They never have to be package-qualified or exported in a
funny way over package-boundaries.

This is true, of course; however, there is a GvIMPORTED_CV flag to
check for overridden builtins. (At least, it looks to me from toke.c
as though that's what it does.)

Ben
 
K

Kenny McCormack

I notice that you skipped over the comment about your patronizing Lucy
science lecture: indeed, I had done that same analysis (which is hardly
difficult) and STILL couldn't figure out why use vars worked but the
version I needed wouldn't.

This is such a funny thread (though I certainly didn't intend it as such
when I posted - I really had hoped for and expected a simple sensible
answer). I don't want to say too much and get the natives any more riled
than necessary, other than to point out how amusing it is to see the
adherents of a language whose motto used to be "There's more than one way
to do it", become so catholic - that is, so obsessed with the notion that
there is only one way for things to be done.

But, anyway, the only reason I am taking time to post this is to ask what
you mean by "Lucy science". It sounds so intriguing. Does it have
anything to do with 7th Heaven?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,161
Latest member
GertrudeMa
Top