A "use Mac::Events" statement appears to interfere with the workings
of a web browsers even if the 'Mac::Events' module is not actually
used in the script. By all the laws of the Medes and Persians (and
Camels) it should be possible to "use" any module without penalty
should it not, since the 'methods' of the module should merely lie
dormant in the script unless called into action?
To demonstrate the effect a primitive server script is appended
below. If run (on line) it will launch the default browser and load
the page "index.html". For the purposes of the experiment
'index.html' can be any HTML page, but to show the effect well, it
should be a fair size, say 25k or so. (Internal calls to graphics
etc. will be silently ignored, but the full page text should be
loaded.)
The script can also be run equally well off-line by setting TCP/IP to
"AppleTalk MacIP" setting "configure" to "manual". For those like me
with dial-up connections that saves cost.
Either way the 'server' uses the 'localhost' address
'http://127.0.0.1' on port number 8888. (In my case 127.0.0.1
corresponds to DN 'localhost.demon.co.uk')
The script works fine with both Netscape 4.7 and InternetExplorer
4.5. However if the line "use Mac::Events" is unleashed (by
un-commenting it), either no page is loaded at all (with the browser
error "attempt to load 127.0.0.1:8888 failed" [IE] or "no connection"
[Netscape]) or the page is only _partially_ loaded.
The phenomenon seems not connected with the line (31) "print
$connection $str". Using the alternative 'syswrite' to avoid standard
I/O it can be shown from the return from 'syswrite' that the whole
file has actually been 'written', even in those cases when the page
is only partially loaded.
Whether or not MacPerl launches its own console window has a
significant effect. If the 'print()' call is suppressed then no
MacPerl widow is launched and the browser usually loads something,
even if that something is only part of the page.
My conclusion from this is that the AppleEvent which opens the
MacPerl window is somehow intercepted by "Mac:Events.pm" which
subsequently interferes in some way with the AppleEvents sent to the
browser. Dose this make any sense?
I am at a loss to imagine what 'Events.pm' might be doing. It does
not seem to be anything to do with "sub Dispatched Event" since
removing it temporarily does not influence the behaviour.
The problem came to light during attempts by Morbus Iff (see a
previous thread [Re: [MacPerl] Mac GUI Q: STDOUT to Mac::Windows?])
to devise a MacWindow "Console" which failed. Investigation showed
the failure to be due to "Events.pm" which lies at the heart of the
all Toolbox GUI modules. The server script below is a skeleton
abstracted from Morbus Iff's own subtle and complex script.
This failed attempt is a pity because a MacWindow GUI would have
brought the MacOS version of Morbus Iff's script up to parity with
other OS's, but the project is frustrated because of the 'Events.pm'
behaviour.
Comments and suggestions would be most welcome,
Alan Fry
-------------
#!perl -w
use strict;
use Cwd;
use IO::Socket;
use Mac::InternetConfig;
use Mac::InternetConfig qw(:DEFAULT $ICInstance);
#use Mac::Events; # HERE LIES THE PROBLEM
$|=1;
my $file = "index.html"; # any old HTML file
my $dir = getcwd; # get script directory
my $port = "8888"; # port to be used
my $url = "http://127.0.0.1:$port/"; # 'localhost' url
open (IN, "$dir:$file"); # open HTML file...
undef $/; my $str = <IN>; $/ = "\n"; # ...and make a string
for (1..9) {
print "$_ Here is line number $_ of 9\n" # print to STDOUT
};
ICGeneralFindConfigFile($ICInstance); # open InternetConfig
ICLaunchURL($ICInstance, 0, $url); # launch browser
my $listen = open_listen(); # start local server
my $connection = $listen->accept; # listen for the browser
if ( $connection ) {
print $connection $str; # send the HTML page
#syswrite($connection, $str, length($str)); # alternative send
close $connection; # close the socket
}
exit;
sub open_listen {
my $listen = IO::Socket::INET->new (
Listen => 10, # connection queue size
LocalPort => $port, # localhost url
Proto => 'tcp',
Timeout => 10
) or return 0;
}