From: Austin S. <te...@of...> - 2003-05-02 10:23:21
|
On Fri, May 02, 2003 at 10:51:46AM +0200, Miguel wrote: > That looks great ... I'll give it a shot. > > A suggestion ... I think it may be helpful for others to put an example > like this in the Expect man page. > > The doc says that exp_init takes a \*FILEHANDLE. > And it looks like to me that Net::Telnet returns an object. > Even now I don't understand why this works ... so on my own I would never > have figured out this solution. > > Just my 2c :) Yeah, I agree, definitely an addition to he docs would be in order. This will be a little weird, but I'll try a brief explanation anyway, which will be inaccurate enough that Randal Schwartz would skin me for saying it, but here goes: First part is that perl has a symbol table which uses "globs", which are what things are named, basically. They are a separate variable type in perl, that holds the other variable types in them that have the same name. They are tagged by having a * in front of them, like *foo. For example: *foo is the glob named 'foo'. $foo is a scalar variable. ${ *foo } (or $*foo) is the scalar contained by the glob *foo. $foo and $*foo are exactly the same thing. %foo is a hash %*foo is that exact same hash. @foo is an array, @*foo is that same array, etc. Filehandles are their own variable type, like a hash or a scalar, but there is no syntax in perl for dealing with them directly. This is a language deficiency, admitted even by Larry Wall. The workaround is to refer to the glob that holds the handle, from which a builtin function will be smart enought to extract and use the handle. Thus you can do something like: fileno(*STDIN); Which perl is nice enough to let you use without having to use the '*', like: fileno(STDIN); and the builtin fileno() function is smart enough to extract the handle from the glob. But if you want a _reference_ to the glob, you can't do \STDIN, because that confuses perl. So you have to explicitly refer to it as \*STDIN. Still awake? Ok, so when you have some sort of IO object, it's really a glob reference. In fact, you can do things like: print *$net_telnet "I'm printing stuff to the Net::Telnet object's handle\r"; The important thing is that $net_telnet is a glob reference where the glob contains a filehandle. Thus \*FILEHANDLE and $net_telnet are the same kind of creature even though they look completely different. I didn't really understand globs when I wrote the early versions of Expect, and some of the very crufty style choices in the module reflect this. But they work, and in general ain't broke. One of these days when I have too much time on my hands I'll submit a massive cleanup. Austin P.S. Am I really responsible for ${${*$self}{exp_Function}}{$escape_sequence}? |