Notes from 2002-10-16 meeting

Tkil tkil-sdpm at scrye.com
Thu Oct 17 19:36:06 CDT 2002


~sdpm~

We had a reasonable turnout last night; seven of us showed up,
including three new faces.

Topics included:

* GUIs for Perl on Win32.

  Specifically, someone wanted to use perl to process files on Win32.
  They wanted a file selector display for this, and Tk was excluded.

  Suggestions included:

  + Look to see if there were Win32 bindings for the "Common Control"
    objects such as File Selector and Color Selector

  + Write a small app in some other language that can interact more
    gracefully with ActiveX objects to display the desired dialog box
    then return the value to a calling perl program

  + Investigate Win32 Perl bindings for other toolkits:  GTK, Qt,
    wxWindows, etc, etc.

* File Globbing, Directory Traversal, etc

  The short question was something like:  "How do I find all the JPEGs
  on my hard disk [using Perl]?"

  The cross examination of that question included:

  + Finding JPEGs by filename or by actual type (the latter typically
    involving opening each one .... brrr.)

  + "On my hard disk" is a bit messy itself, on win32 with drive
    letters, on unix with mounts.

  Various solutions discussed:

  + File::Find, and its relationship to / heritage from the unix
    "find" command.

  + The differences between globbing (file wildcards) and regular
    expressions.  This brought back memories:

      http://groups.google.com/groups?selm=glnqtgszo.fsf%40scrye.com

* Identifying References, Blessings

  The short answer is to use the "ref" function.  There are a few
  tricks to this, however; the main being that blessed objects will
  return only their package name to "ref", with no indication of the
  type of reference underlying it.  You can get the type, even of a
  blessed reference, by stringifying it:

    package SomePackage;
    package main;
    my $obj = bless {}, SomePackage;
    print ref $obj; # prints "SomePackage"
    print "$obj";   # prints "SomePackage=HASH(0xXXXXXXXX)"

  So you'll occasionally see things like this:

    my ($real_ref_type) = ( "$obj" =~ m/=([A-Z]+)/ );

  Which, for $obj above, sets $real_ref_type to "HASH".

* Stringification, Reference Object Lifetimes

  This provided a segue into a fairly subtle trap.  Perl hash keys can
  only be strings (although the values in hashes can be any scalar
  type).  Trying to use a reference as a hash key will work, but the
  key will be just a string -- if there are no other live references
  to the object, that object will be destroyed.

  This shows up when you build objects at one point in the program,
  but want to use them elsewhere.  A natural way of storing those
  objects is in a hash -- but using the objects only as the key will
  not work.  This can happen if you had been using hash keys to
  indicate presence:

    my %seen_host;
    foreach my $host ( @hostnames )
    {
        $seen_host{$host} = 1;
    }

  If you decide that you want to open a connection to each of these
  hosts, you might try to modify it like so:

    my %seen_host;
    foreach my $host ( @hostnames )
    {
        my $sock = IO::Socket::INET->new( PeerAddr => $host,
                                          PeerPort => 80 );
        $seen_host{$sock} = 1; # broken!
    }

  The problem is that $sock is stringified to become the key in
  %seen_hosts -- but that doesn't preserve the reference count on the
  object itself.  At the end of the scope of the foreach loop, $sock
  goes out of scope and is destroyed.  When you try to recover them
  later:

    my $CRLF = "\x0d\x0a";
    while ( my $sock = each %seen_host )
    {
        # oops, $sock is just a string!
        print $sock "GET / HTTP/1.0", $CRLF, $CRLF;
    }

  It won't work.

  The fix is to stash a copy of the socket, too:
    
    my %seen_host;
    foreach my $host ( @hostnames )
    {
        my $sock = IO::Socket::INET->new( PeerAddr => $host,
                                          PeerPort => 80 );
        $seen_host{$sock} = { sock => $sock,
                              host => $host };
    }

    my $CRLF = "\x0d\x0a";
    while ( my ($sock, $href) = each %seen_host )
    {
        print { $href->{sock} } "GET / HTTP/1.0", $CRLF, $CRLF;
    }

A few topics that would benefit from further discussion on the list:

* Threading in Perl

  Anyone used it?  Advice?  Any idea when it will show up in
  ActivePerl?

* Win32 GUIs in Perl

  Experiences?

~sdpm~

The posting address is: san-diego-pm-list at hfb.pm.org

List requests should be sent to: majordomo at hfb.pm.org

If you ever want to remove yourself from this mailing list,
you can send mail to <majordomo at happyfunball.pm.org> with the following
command in the body of your email message:

    unsubscribe san-diego-pm-list

If you ever need to get in contact with the owner of the list,
(if you have trouble unsubscribing, or have questions about the
list itself) send email to <owner-san-diego-pm-list at happyfunball.pm.org> .
This is the general rule for most mailing lists when you need
to contact a human.




More information about the San-Diego-pm mailing list