[18328] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 496 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Mar 15 18:11:15 2001

Date: Thu, 15 Mar 2001 15:10:26 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <984697825-v10-i496@ruby.oce.orst.edu>
Content-Type: text

Perl-Users Digest           Thu, 15 Mar 2001     Volume: 10 Number: 496

Today's topics:
    Re: FAQ 7.12:   What's a closure? (Ilya Zakharevich)
    Re: FAQ 7.12:   What's a closure? <bart.lateur@skynet.be>
    Re: FAQ 7.12:   What's a closure? (Abigail)
    Re: FAQ 7.12:   What's a closure? <uri@sysarch.com>
    Re: FAQ 7.12:   What's a closure? (Abigail)
    Re: FAQ 7.12:   What's a closure? <webmaster@webdragon.munge.net>
    Re: FAQ 7.12:   What's a closure? <bart.lateur@skynet.be>
    Re: FAQ 7.12:   What's a closure? (Abigail)
    Re: FAQ 7.12:   What's a closure? <uri@sysarch.com>
    Re: FAQ 7.12:   What's a closure? <uri@sysarch.com>
    Re: Formatting HTML using Perl <webmaster@webdragon.munge.net>
        Getopt::Std swallows argument even if ":" not specified (LMC)
    Re: How do I delete (ignore) part of a string? (David H. Adler)
    Re: How to Print "system" failure ...was <Print own "di (BUCK NAKED1)
    Re: How to Print "system" failure ...was <Print own "di (BUCK NAKED1)
    Re: How to Print "system" failure ...was <Print own "di <mischief@velma.motion.net>
        Digest Administrivia (Last modified: 16 Sep 99) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: 15 Mar 2001 19:52:47 GMT
From: ilya@math.ohio-state.edu (Ilya Zakharevich)
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <98r6if$7s2$1@charm.magnus.acs.ohio-state.edu>

[A complimentary Cc of this posting was sent to Anno Siegel
<anno4000@lublin.zrz.tu-berlin.de>],
who wrote in article <98q2ti$kr5$1@mamenchi.zrz.TU-Berlin.DE>:
> This FAQ excerpt, as well as other places in the documentation,
> insist that a closure be an anonymous subroutine.  In my view, the
> characteristic property of a closure is that it keeps lexicals alive
> that would otherwise have gone out of scope.  But that is also true
> with a named subroutine that is defined inside a bare block:
> 
>     {
>         my $state = 0;
>         sub toggle { $state = not $state; }
>     }
> 
> So would this not be a closure?  If it said "$toggle = sub { ...}"
> instead, would it be?

Your usage of terms is slightly misleading.  $toggle is "alive"
anyway, no matter whether you have sub toggle or not.  [This may be
considered as a bug, though.  And it *is* out-of-scope.]

For me a "closure" is a thingy which

 a) may be called exactly as a subroutine;

 b) is *generated* by a factory;

 c) (optional "efficiency edict") in the factory-generated stuff the
    "code" is "shared", only the "attached data" changes.

(a) prohibits the Bart's example of a closure-like object; (b)
prohibits your example; (c) prohibits the rewrite of

  sub make_a_constant {
      my $retvalue = shift;
      sub { $retvalue }
  }

as

  sub make_a_constant {
      my $retvalue = shift;
      eval "sub { $retvalue }";
  }

Ilya


------------------------------

Date: Thu, 15 Mar 2001 20:10:43 GMT
From: Bart Lateur <bart.lateur@skynet.be>
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <rb82bto053d85ebovnk4fcp1ggsd2ckrti@4ax.com>

Uri Guttman wrote:

>i don't see any closures there. no anon sub refers to a variable in its
>parent's space.

No... all I'm saying is that closures do not necessarily buy you
anything. There's nothing you can do with a closure that you can't do
with OO.

-- 
	Bart.


------------------------------

Date: 15 Mar 2001 20:20:44 GMT
From: abigail@foad.org (Abigail)
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <slrn9b290s.p0e.abigail@tsathoggua.rlyeh.net>

Ilya Zakharevich (ilya@math.ohio-state.edu) wrote on MMDCCLIII September
MCMXCIII in <URL:news:98r6if$7s2$1@charm.magnus.acs.ohio-state.edu>:
() 
() For me a "closure" is a thingy which
() 
()  a) may be called exactly as a subroutine;
() 
()  b) is *generated* by a factory;
() 
()  c) (optional "efficiency edict") in the factory-generated stuff the
()     "code" is "shared", only the "attached data" changes.

Most people (but not me) would add

    d) There is (lexical) data attached.


But I wouldn't say that a degenerated case of an empty set of attached
data should be stripped of its title 'closure'. After all, from the
language POV, you can't notice the difference.


Abigail
-- 
map{${+chr}=chr}map{$_=>$_^ord$"}$=+$]..3*$=/2;        
print "$J$u$s$t $a$n$o$t$h$e$r $P$e$r$l $H$a$c$k$e$r\n";


------------------------------

Date: Thu, 15 Mar 2001 20:22:29 GMT
From: Uri Guttman <uri@sysarch.com>
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <x7r8zy93zt.fsf@home.sysarch.com>

>>>>> "BL" == Bart Lateur <bart.lateur@skynet.be> writes:

  BL> No... all I'm saying is that closures do not necessarily buy you
  BL> anything. There's nothing you can do with a closure that you can't do
  BL> with OO.

but with closures you get much better and true encapsulation. also try
using OO to install methods that are created by AUTOLOAD. much easier to
use closures there. in fact i am not sure how you could dynamically
create common accessors without closures (or string eval which is bad).

closures can be partly eumulated by OO but not replaced.

think of closures as an idiom, it is a code technique. OO is a
programming style and higher level. comparing them is not productive IMO

uri

-- 
Uri Guttman  ---------  uri@sysarch.com  ----------  http://www.sysarch.com
SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting
The Perl Books Page  -----------  http://www.sysarch.com/cgi-bin/perl_books
The Best Search Engine on the Net  ----------  http://www.northernlight.com


------------------------------

Date: 15 Mar 2001 20:24:57 GMT
From: abigail@foad.org (Abigail)
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <slrn9b298p.p0e.abigail@tsathoggua.rlyeh.net>

Bart Lateur (bart.lateur@skynet.be) wrote on MMDCCLIII September MCMXCIII
in <URL:news:rb82bto053d85ebovnk4fcp1ggsd2ckrti@4ax.com>:
;; Uri Guttman wrote:
;; 
;; >i don't see any closures there. no anon sub refers to a variable in its
;; >parent's space.
;; 
;; No... all I'm saying is that closures do not necessarily buy you
;; anything. There's nothing you can do with a closure that you can't do
;; with OO.


Which is a pointless argument. There's nothing in OO that you can't do
purely procedurial. There's nothing in procedurial languages you
can't do in a goto spagetti.

OTOH, there are a lot of reason you might want to use closure in
Perl. It's implementation of OO, for instance.


Abigail


------------------------------

Date: 15 Mar 2001 21:04:37 GMT
From: "Scott R. Godin" <webmaster@webdragon.munge.net>
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <98rap5$lqh$1@216.155.32.198>

In article <x7r8zy93zt.fsf@home.sysarch.com>, Uri Guttman 
<uri@sysarch.com> wrote:

 | but with closures you get much better and true encapsulation. also try
 | using OO to install methods that are created by AUTOLOAD. much easier to
 | use closures there. in fact i am not sure how you could dynamically
 | create common accessors without closures (or string eval which is bad).
 | 
 | closures can be partly eumulated by OO but not replaced.
 | 
 | think of closures as an idiom, it is a code technique. OO is a
 | programming style and higher level. comparing them is not productive IMO

indeed. 

I found the portion of Damian Conway's "Object Oriented Perl" that 
detailed this to be most enlightening. (i.e. the early sections 
regarding the tutorial CD::Music class built during the course of the 
discussion therein, where the $count variable is kept in a closure 
containing the subroutines that update the $count whenever an object is 
created or destroyed.)

-- 
unmunge e-mail here:
#!perl -w
print map {chr(ord($_)-3)} split //, "zhepdvwhuCzhegudjrq1qhw"; 
# ( damn spammers. *shakes fist* take a hint. =:P )


------------------------------

Date: Thu, 15 Mar 2001 22:36:03 GMT
From: Bart Lateur <bart.lateur@skynet.be>
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <70h2btg1ljuumh87fipcvr10sefa50e1k3@4ax.com>

Abigail wrote:

>OTOH, there are a lot of reason you might want to use closure in
>Perl. It's implementation of OO, for instance.

Now there's an interesting thought. So, care to expand on what this
would look like?

-- 
	Bart.


------------------------------

Date: 15 Mar 2001 22:42:41 GMT
From: abigail@foad.org (Abigail)
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <slrn9b2hb1.p0e.abigail@tsathoggua.rlyeh.net>

Scott R. Godin (webmaster@webdragon.munge.net) wrote on MMDCCLIII
September MCMXCIII in <URL:news:98rap5$lqh$1@216.155.32.198>:
 .. In article <x7r8zy93zt.fsf@home.sysarch.com>, Uri Guttman 
 .. <uri@sysarch.com> wrote:
 .. 
 ..  | but with closures you get much better and true encapsulation. also try
 ..  | using OO to install methods that are created by AUTOLOAD. much easier to
 ..  | use closures there. in fact i am not sure how you could dynamically
 ..  | create common accessors without closures (or string eval which is bad).
 ..  | 
 ..  | closures can be partly eumulated by OO but not replaced.
 ..  | 
 ..  | think of closures as an idiom, it is a code technique. OO is a
 ..  | programming style and higher level. comparing them is not productive IMO
 .. 
 .. indeed. 
 .. 
 .. I found the portion of Damian Conway's "Object Oriented Perl" that 
 .. detailed this to be most enlightening. (i.e. the early sections 
 .. regarding the tutorial CD::Music class built during the course of the 
 .. discussion therein, where the $count variable is kept in a closure 
 .. containing the subroutines that update the $count whenever an object is 
 .. created or destroyed.)


Just for kicks, here's a way to do OO using closures. That is, MI, SUPER::
and AUTOLOAD, without using bless, or the need to pack your instances
variables in a structure.



package OO::Closures;

################################################################################
#
# $Author: abigail $
#
# $Date: 2001/03/15 22:32:22 $
#
# $Id: Closures.pm,v 1.3 2001/03/15 22:32:22 abigail Exp abigail $
#
# $Log: Closures.pm,v $
# Revision 1.3  2001/03/15 22:32:22  abigail
# Fixed copyright/license/email address.
#
# Revision 1.2  1999/08/02 06:06:04  abigail
# Bug fixes and more efficient use of code (Rick Delaney).
# Free and open software copyright/license.
# Scalar references as methods (to complement for Eiffel like features).
# CPAN friendly module.
#
# Revision 1.1  1998/10/01 22:54:57  abigail
# Initial revision
#
#
#
################################################################################

use vars qw /$VERSION/;

($VERSION) = '$Revision: 1.3 $' =~ /(\d+.\d+)/;

sub import {
    my $my_package       = __PACKAGE__;
    my $foreign_package  =  caller;
    my $my_sub           = 'create_object';
    shift;
    my $foreign_sub      =  @_ ? shift : $my_sub;

    no strict 'refs';
    *{"${foreign_package}::$foreign_sub"} = \&{"${my_package}::$my_sub"};
}

sub croak {
    require Carp;
    goto &Carp::croak;
}

sub create_object {
    my ($methods, $ISA, $is_base) = @_;

    sub {
        my ($method, @args) = @_;
        my ($call_super, $class);

        if ($method =~ /^((?:[^:]+|:[^:])*)::(.*)/s) {
            $class  = $1;
            $method = $2;
        }

        if (exists   $methods -> {$method} && !defined $class) {
            return   $methods -> {$method} -> (@args) if
               ref   $methods -> {$method} eq 'CODE';
            return ${$methods -> {$method}} if 
               ref   $methods -> {$method} eq 'SCALAR';
            die "Illegal method ($method) in object.\n";
        }

        my  @supers;
        if (defined $class && ($class ne 'SUPER' || exists $ISA -> {$class})) {
            unless (exists $ISA -> {$class}) {
                croak "No class ($class) found\n";
            }
            @supers = ($ISA -> {$class});
        }
        else {@supers = values %$ISA}

        # Go looking for the method in an inherited object.
        foreach my $super (@supers) {
            return eval {$super -> ($method => @args)} unless $@;
            croak $@ unless $@ =~ /^No such method/;
        }

        unless ($is_base) {
            # This is the base object. So, we'll look for AUTOLOAD.
            return $methods -> {AUTOLOAD} -> ($method => @args) if exists
                   $methods -> {AUTOLOAD} && !defined $class;

            # Check %ISA for AUTOLOAD.
            foreach my $super (@supers) {
                return eval {$super -> (AUTOLOAD => $method, @args)} unless $@;
                croak $@ unless $@ =~ /^No such method/;
            }
        }

        croak "No such method ($method) found";
    }
}


1;


__END__

=pod

=head1 NAME

OO::Closures - Object Oriented Programming using Closures.

=head1 SYNOPSIS

    use OO::Closures;

    sub new {
        my (%methods, %ISA, $self);
        $self = create_object (\%methods, \%ISA, !@_);

        ...

        $self;
    }

=head1 DESCRIPTION

This package gives you a way to use Object Oriented programming using
Closures, including multiple inheritance, C<SUPER::> and AUTOLOADing.

To create the object, call the function C<create_object> with three
arguments, a reference to a hash containing the methods of the object,
a reference to a hash containing the inherited objects, and a flag
determining whether the just created object is the base object or
not. This latter flag is important when it comes to trying C<AUTOLOAD>
after not finding a method.

C<create_object> returns a closure which will act as the new object.

Here is an example of the usage:

    use OO::Closures;
    sub dice {
        my (%methods, %ISA, $self);
        $self = create_object (\%methods, \%ISA, !@_);

        my $faces = 6;

        $methods {set}  = sub {$faces = shift;};
        $methods {roll} = sub {1 + int rand $faces};

        $self;
    }

It is a simple object representing a die, with 2 methods, C<set>, to set
the number of faces, and C<roll>, to roll the die. It does not inherit
anything. To make a roll on a 10 sided die, use:

    (my $die = dice) -> (set => 10);
    print $die -> ('roll');

Note that since the objects are closures, method names are the first
arguments of the calls.


=head1 OBJECT VARIABLES

One can make object variables available to the outside world as well.
Just like in Eiffel, for an outsider this will be indistinguishable
from accessing a argumentless method. (However, in a Perlish fashion,
we will actually allow arguments in the call). To do so, instead of
putting a code reference in the %methods hash, put a reference to a
scalar in the hash. Note that to the outside world, no more than read
only access to the variable is given.

Here is an example:

    sub dice {
        my (%methods, %ISA, $self);
        $self = create_object (\%methods, \%ISA, !@_);

        my $faces = 6;

        $methods {set}   = sub {$faces = shift;};
        $methods {roll}  = sub {1 + int rand $faces};

        $methods {faces} = \$faces;

        $self;
    }

    (my $die = dice) -> (set => 10);
    print $die -> ('faces');

This will print C<10>.


=head1 INHERITANCE

To use inheritance, we need to set the C<%ISA> hash. We also need to
pass ourselves to the classes we inherited, so an inherited class can
find the base object. (This is similar to the first argument of the
constructor when using regular objects).

Here is an example that implements multi dice, by subclassing C<dice>.
We will also give C<dice> a method C<print_faces> that prints the number
of faces and returns the object.

    use OO::Closures;

    sub dice {
        my (%methods, %ISA, $self);
        $self = create_object (\%methods, \%ISA, !@_);
        my $this_object = shift || $self;

        my $faces = 6;

        $methods {set}         = sub {$faces = shift};
        $methods {roll}        = sub {1 + int rand $faces};
        $methods {print_faces} = sub {print "Faces: $faces\n"; $this_object};

        $self;
    }

    sub multi_dice {
        my (%methods, %ISA, $self);
        $self = create_object (\%methods, \%ISA, !@_);
        my $this_object = shift || $self;

        %ISA  = (dice => dice $this_object);

        my $amount = 1;

        $methods {amount} = sub {$amount = shift};
        $methods {roll}   = sub {
            my $sum = 0;
            foreach (1 .. $amount) {$sum += $self -> ('dice::roll')}
            $sum;
        };

        $self;
    }

    my $die = multi_dice;
    $die -> (set    => 7);
    $die -> (amount => 4);
    print $die -> ('print_faces') -> ('roll'), "\n";
    __END__


Notice the line C<my $this_object = shift || $self;>. That will make
C<$this_object> contain the base object, unlike C<$self> which is the
instance of the current class.

The class C<dice> is subclassed in C<multi_dice> by calling C<dice>
with an extra argument, the base object. Now it's known that C<dice>
is subclassed, and looking for C<AUTOLOAD> if it cannot find the
requested method should not happen; that will be triggered by the
base object.

Inherited classes are named, but they are named by the inheriter,
not the inheritee. This allows you to inherit the same class multiple
times, and getting separate data and method space for it.

When searching for methods in the inheritance tree, no order will be
garanteed. If you subclass multiple classes defining the methods with
the same name, it's better to mask those methods and explicitely
redirect the call to the class you want it to handle.

You can call a method by prepending its class name(s); just like
regular objects. 

Inherited classes are stored in the C<%ISA> hash, but since this variable
is private to the object, each object can have its own inheritance
structure. If you change a class, existing objects of the class will not
be modified.

The pseudo class 'SUPER::' works the same way as regular objects do,
except that it works the right way. It will resolve 'SUPER::' depending
on the inherited classes of the object the method is called in; not
on the C<@ISA> of the package the call is made from.

=head1 C<use OO::Closures;>

By default, the module C<OO::Closures> exports the function C<create_object>.
If you want this function to be known by another name, give that name
as an argument to the C<use> statement.

    use OO::Closure 'other_name';

Now you create objects with C<other_name (\%methods, \%ISA, !@_);>

=head1 BUGS

This documentation uses the word 'class' in cases where it's not really
a class in the sense of the usual object oriented way. Mark-Jason Dominus 
calls this I<class-less> object orientism.

=head1 HISTORY

    $Log: Closures.pm,v $
    Revision 1.3  2001/03/15 22:32:22  abigail
    Fixed copyright/license/email address.

    Revision 1.2  1999/08/02 06:06:04  abigail
    Bug fixes and more efficient use of code (Rick Delaney).
    Free and open software copyright/license.
    Scalar references as methods (to complement for Eiffel like features).
    CPAN friendly module.

    Revision 1.1  1998/10/01 22:54:57  abigail
    Initial revision


=head1 AUTHOR

This package was written by Abigail, I<abigail@foad.org>.

=head1 COPYRIGHT and LICENSE

This program is copyright 1998-2001 by Abigail

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

=cut


__END__


Abigail
-- 
$_ = "\112\165\163\1648\141\156\157\164\150\145\1628\120\145"
   . "\162\1548\110\141\143\153\145\162\0128\177"  and &japh;
sub japh {print "@_" and return if pop; split /\d/ and &japh}


------------------------------

Date: Thu, 15 Mar 2001 22:51:08 GMT
From: Uri Guttman <uri@sysarch.com>
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <x7lmq68x43.fsf@home.sysarch.com>

>>>>> "BL" == Bart Lateur <bart.lateur@skynet.be> writes:

  BL> Abigail wrote:
  >> OTOH, there are a lot of reason you might want to use closure in
  >> Perl. It's implementation of OO, for instance.

  BL> Now there's an interesting thought. So, care to expand on what this
  BL> would look like?

like i said, read about OO closures in OOP by conway.

uri

-- 
Uri Guttman  ---------  uri@sysarch.com  ----------  http://www.sysarch.com
SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting
The Perl Books Page  -----------  http://www.sysarch.com/cgi-bin/perl_books
The Best Search Engine on the Net  ----------  http://www.northernlight.com


------------------------------

Date: Thu, 15 Mar 2001 23:00:45 GMT
From: Uri Guttman <uri@sysarch.com>
Subject: Re: FAQ 7.12:   What's a closure?
Message-Id: <x7hf0u8wo0.fsf@home.sysarch.com>

>>>>> "A" == Abigail  <abigail@foad.org> writes:

  A> Just for kicks, here's a way to do OO using closures. That is, MI, SUPER::
  A> and AUTOLOAD, without using bless, or the need to pack your instances
  A> variables in a structure.

  A> package OO::Closures;

also see Class::Classless on CPAN for a different approach.  i believe
it also uses closures and perl refs but none of perl's builtin OO stuff.

uri

-- 
Uri Guttman  ---------  uri@sysarch.com  ----------  http://www.sysarch.com
SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting
The Perl Books Page  -----------  http://www.sysarch.com/cgi-bin/perl_books
The Best Search Engine on the Net  ----------  http://www.northernlight.com


------------------------------

Date: 15 Mar 2001 19:45:59 GMT
From: "Scott R. Godin" <webmaster@webdragon.munge.net>
Subject: Re: Formatting HTML using Perl
Message-Id: <98r65n$dk3$0@216.155.32.198>

In article <m1wv9tmqde.fsf@halfdome.holdit.com>, merlyn@stonehenge.com 
(Randal L. Schwartz) wrote:

 | Michael> Like <P> does not necessarily have to have a </P> tag.
 | 
 | It does in XHTML, which is what the world is moving to.  And if you
 | had been using CGI.pm's HTML shortcuts, you're already generating
 | nearly all of XHTML correctly anyway. :)

 
Thank god for that. Dealing with b0rked html code is .. *shaking head* 
 .. I don't think webster has the right word to describe my feelings on 
this. Considering that HTML 4 has been a 'standard' since 1997, it 
continually amazes me how long it took the two major browser players to 
'fall into some randomized subset of compliance' with it, considering 
the fact that all OTHER computer technology is pushing the bleeding edge 
to ludicrous extremeties(sp?). 

I absolutely love the way that CGI.pm's subroutines allow me to almost 
completely mimic the way that HTML 4.0 parses: 

  push @htmldata,  
    header, 
    start_html({-Title=> escapeHTML("$UT::mapname by $UT::author -- 
ReadMe File"),
                
-background=>'../NetGamesUSA.com/ngStats/html/graphics/blue_white.gif',
                -bgcolor=>'white',
                -text=>'black',
                -"link"=>'blue',
                -vlink=>'red',}),
    comment("MAPSCAN DAT - Author=$UT::author - Email=$UT::email"),
    comment("$internal_comment1"); 

  push @htmldata, 
    table({-border=>'0', -cellpadding=>'9', -cellspacing=>'0', 
-width=>'580'}, 
    Tr( 
    td({-valign=>'top', -rowspan=>'3'}, 
        
img({-src=>'../NetGamesUSA.com/ngStats/html/graphics/UT_Logo_Large_Button
 .gif', 
             -width=>'106',
             -height=>'106',
             -hspace=>'5'}),
      ),
     td( p({-align=>'center'}, 
           
img({-src=>'../NetGamesUSA.com/ngStats/html/graphics/unreallogo.gif',
               }),
          ),
         h1({-align=>'center'}, escapeHTML("$UT::mapname ReadMe for"), 
br(), escapeHTML("$UT::game")),
         h3({-align=>'center'}, "Release Date: $UT::release_date"),
         hr({-size=>'5', -width=>'70%', -align=>'center'}), 
    table({-border=>'0', -cellspacing=>'2', -cellpadding=>'4', 
-width=>'570'}, 
    Tr(
      td({-valign=>'top', -align=>'right'}, b("Title:") ),
      td({-valign=>'top'}, escapeHTML("$UT::mapname") ),
    ),

etc etc etc. :) 

when you need it, it's there, beautifully.

-- 
unmunge e-mail here:
#!perl -w
print map {chr(ord($_)-3)} split //, "zhepdvwhuCzhegudjrq1qhw"; 
# ( damn spammers. *shakes fist* take a hint. =:P )


------------------------------

Date: Thu, 15 Mar 2001 16:03:34 -0500
From: "Antoine Beaupre (LMC)" <lmcabea@lmc.ericsson.se>
Subject: Getopt::Std swallows argument even if ":" not specified?
Message-Id: <3AB12E26.CBCC9876@lmc.ericsson.se>

Hi.

<angry-tired-programmer-rant>

I expected the following code:

  my (%opts) = ();
  message "ARGV is @ARGV now";
  getopt('qvf:', \%opts);
  message "ARGV is @ARGV now";

To output something like:

====> ARGV is -v -q -v P1 OU/ADMINDATA now
====> ARGV is P1 OU/ADMINDATA now

but instead I had:

====> ARGV is -v -q -v P1 OU/ADMINDATA now
====> ARGV is OU/ADMINDATA now

Don't give me that "it's-not-a-bug-it's-a-feature" crap. :) I believe
that the parser should leave the argument in @ARGV if it doesn't need
it!

It's always possible to recuperate the "P1" arg if it was the latest
arg, but I think this behavior is bad.

It should be $opt{'b'} = <int> where 'b' is a boolean flag and <int> is
incremented at each encounter of -b. 

No?

</angry-tired-programmer-rant>

This is perl, version 5.005_03 built for sun4-solaris by the way. :)

Thanks

A.

--
La sémantique est la gravité de l'abstraction.


------------------------------

Date: 15 Mar 2001 22:57:22 GMT
From: dha@panix6.panix.com (David H. Adler)
Subject: Re: How do I delete (ignore) part of a string?
Message-Id: <slrn9b2i6h.6lh.dha@panix6.panix.com>

On Tue, 13 Mar 2001 01:32:04 GMT, Nancy <pigpen@easynews.com> wrote:
>"Tad McClellan" <tadmc@augustmail.com> wrote in message
>news:slrn9apgou.sip.tadmc@tadmc26.august.net...
>> Nancy <pigpen@easynews.com> wrote:
>>
>> >I should have prefaced my post with the fact
>> >that I'm not a programmer.  I am modifying a very good off-the-shelf
>script.
>>
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>
>> Those are extremely rare.
>>
>> Since you are not a programmer, how do you arrive at the conclusion
>> that it is "very good"?
>
>The programmer doesn't use Flash on his site web site.

Actually, I think that may be the most reasonable response to that
question I've heard in a long time...

dha

-- 
David H. Adler - <dha@panix.com> - http://www.panix.com/~dha/
Well (s)he is only a type of deer after all so its particularly
spectacular to have learnt English from only 'A Stranger in a Strange
Land' and 'A Clockwork Orange'	- Jonathan Stowe in c.l.p.misc
(It was even better *in* context... :-)


------------------------------

Date: Thu, 15 Mar 2001 13:05:27 -0600 (CST)
From: dennis100@webtv.net (BUCK NAKED1)
Subject: Re: How to Print "system" failure ...was <Print own "die" message"
Message-Id: <12490-3AB11277-61@storefull-248.iap.bryant.webtv.net>

[minimized quoting since WebTV doesn't quote well and PC is down]

> bigiain@mightymedia.com.au 
>  Whats the return value of system? (perldoc -f system) 

False? (I did your suggested tests, btw).

> Whats does gtar return on success? 

Nothing, so that'd be "false"?

[ SNIPPED lots of good info and suggestions ]

> The simple answer is to change the "or" 
> an "and", but just telling you to do that  > wouldn't have helped you
understand  *why*... 

I changed the "or print(or die)" to "and print(and die)" and it still
printed the error message although the operation was successful. 

I saw Bart's post and I've looked at $SIG alarm, as well as lipc, -f
system, perlvar, etc. I thought this would be a quick task... that I'd
just go into my script and add the simple die messages to check for
success. I had no idea that using "system" required a different method.
And from what I've read, it looks like errors are in a different place
also when you use "system" ...$? as compared to $!. I'm still so
confused.

I really appreciate all of the time you've spent trying to help me. Do
you have an example of checking for success with a "system" command so
that I can study it. 

Regards,
--Dennis



------------------------------

Date: Thu, 15 Mar 2001 15:19:52 -0600 (CST)
From: dennis100@webtv.net (BUCK NAKED1)
Subject: Re: How to Print "system" failure ...was <Print own "die" message"
Message-Id: <12490-3AB131F8-70@storefull-248.iap.bryant.webtv.net>

I've been searching the net for hours trying to find an answer. Though I
found no sample code, It looks like I need to study "eval"  for checking
success of a "system" operation. Is that correct? If so, why didn't you
mention it? Is using "eval" not the best way?

'course I don't understand why something like 

system("tar -zxf file.tar.gz 2>&1")==0 or die "Can't untar file: $!\n";
 ..OR...

die "Can't untar file: $!\n" unless system("tar -zxf file.tar.gz
2>&1")==0;

won't work either.

--Dennis



------------------------------

Date: Thu, 15 Mar 2001 23:00:48 -0000
From: Chris Stith <mischief@velma.motion.net>
Subject: Re: How to Print "system" failure ...was <Print own "die" message"
Message-Id: <tb2id0a1v199c9@corp.supernews.com>

BUCK NAKED1 <dennis100@webtv.net> wrote:
> [minimized quoting since WebTV doesn't quote well and PC is down]

>> bigiain@mightymedia.com.au 
>>  Whats the return value of system? (perldoc -f system) 

> False? (I did your suggested tests, btw).

Zero (`0'), which is false to Perl.

>> Whats does gtar return on success? 

> Nothing, so that'd be "false"?

Every program in Unix returns something. Returning an error
code does not mean printing something to stdout. 

> [ SNIPPED lots of good info and suggestions ]

>> The simple answer is to change the "or" 
>> an "and", but just telling you to do that  > wouldn't have helped you
> understand  *why*... 

It's simple to change out `or' for `and' here, but it's more
clear (slightly) to do this:

   !( system('foo') ) || die "Couldn't do foo!";

> I changed the "or print(or die)" to "and print(and die)" and it still
> printed the error message although the operation was successful. 

You need to negate the boolean return of system.

NOTE: 
`Boolean' is named after George Boole, who realized most any
value could be broken down into a series of yes/no or true/false
values. (The guy who brought that to computers was Shannon.)
A boolean value is one that is in one of two possible states.

> I saw Bart's post and I've looked at $SIG alarm, as well as lipc, -f
> system, perlvar, etc. I thought this would be a quick task... that I'd
> just go into my script and add the simple die messages to check for
> success. I had no idea that using "system" required a different method.
> And from what I've read, it looks like errors are in a different place
> also when you use "system" ...$? as compared to $!. I'm still so
> confused.

system() returns 0 on success, as that's what programs return
to the outside world on success (which is related to why you
find that some program exit on error with an "Error code" -- 0
for an error code means success, get it? ;-)

Right about the error variable. You might need to do both
in the same statement or something, so it's actually good
to have more than one variable for the errors. We'll save
discussion for why Perl actually does it this way to someone
who knows.

> I really appreciate all of the time you've spent trying to help me. Do
> you have an example of checking for success with a "system" command so
> that I can study it. 

    !(system('foo')) || die "blah $?\n";

or

    system('foo') && die "blah $?\n";


Chris

-- 
Christopher E. Stith
Disclaimer: Actual product may not resemble picture in ad in any way.



------------------------------

Date: 16 Sep 99 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 16 Sep 99)
Message-Id: <null>


Administrivia:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

| NOTE: The mail to news gateway, and thus the ability to submit articles
| through this service to the newsgroup, has been removed. I do not have
| time to individually vet each article to make sure that someone isn't
| abusing the service, and I no longer have any desire to waste my time
| dealing with the campus admins when some fool complains to them about an
| article that has come through the gateway instead of complaining
| to the source.

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 496
**************************************


home help back first fref pref prev next nref lref last post