[26065] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 8270 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sat Jul 23 00:05:21 2005

Date: Fri, 22 Jul 2005 21:05:05 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Fri, 22 Jul 2005     Volume: 10 Number: 8270

Today's topics:
    Re: copy contructor <abigail@abigail.nl>
    Re: copy contructor <emschwar@pobox.com>
    Re: copy contructor <abigail@abigail.nl>
    Re: copy contructor <emschwar@pobox.com>
    Re: copy contructor <abigail@abigail.nl>
    Re: Regex (?(?{CODE})) has too many branches <spam-block-@-SEE-MY-SIG.com>
    Re: Regex (?(?{CODE})) has too many branches <abigail@abigail.nl>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: 22 Jul 2005 22:35:38 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: copy contructor
Message-Id: <slrnde2t5q.7fo.abigail@alexandra.abigail.nl>

Anno Siegel (anno4000@lublin.zrz.tu-berlin.de) wrote on MMMMCCCXLI
September MCMXCIII in <URL:news:dbl9pb$g3r$2@mamenchi.zrz.TU-Berlin.DE>:

> [[ Snipped for brevity ]]


Here's how I would subclass Angry::Snake. Note that I subclass the
original Angry::Snake, without requiring it to have an "accessor".


    package Angry::Snake;
 
    sub new {
        bless \do {my $c = int rand 5} => shift;
    }
 
    sub poke_it_with_a_stick {
        my $snake = shift;
        $snake -> attack if $$snake -- < 0;
    }
 
    sub attack { ... }



    package Sleepy::Snake; {
        use Scalar::Util qw 'refaddr';

        our @ISA = qw /Angry::Snake/;

        my %sleepiness;   # Store the attribute in a lexical variable.

        sub set_sleepiness {
            my $snake = shift;
            $sleepiness {refaddr $snake} = shift;
            $snake;
        }
        sub sleepiness {
            my $snake = shift;
            $sleepiness {refaddr $snake};
        }
            
        sub poke_it_with_a_stick {
            my $snake = shift;
            $snake -> SUPER::poke_it_with_a_stick
                      if rand > $snake -> sleepiness;
        }

        sub DESTROY {
            my $snake = shift;
            delete $sleepiness {refaddr $snake};
        }
    }

    package main;

    my $snake = Sleepy::Snake -> new -> set_sleepiness (0.5);


Note that Sleepy::Snake doesn't have its own constructor. Nor does it rely 
on how Angry::Snake has been implemented in any way. It doesn't require
its super class to make accessors available. It doesn't force anything
on a potential subclass either.


Abigail
-- 
perl -wlne '}print$.;{' file  # Count the number of lines.


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

Date: Fri, 22 Jul 2005 17:53:32 -0600
From: Eric Schwartz <emschwar@pobox.com>
Subject: Re: copy contructor
Message-Id: <etoy87yxurn.fsf@wilson.emschwar>

Abigail <abigail@abigail.nl> writes:
> Here's how I would subclass Angry::Snake. Note that I subclass the
> original Angry::Snake, without requiring it to have an "accessor".
>
>     package Angry::Snake;
>  
>     sub new {
>         bless \do {my $c = int rand 5} => shift;
>     }
>  
>     sub poke_it_with_a_stick {
>         my $snake = shift;
>         $snake -> attack if $$snake -- < 0;
>     }
>  
>     sub attack { ... }

<snip rest of example>

Ow.  Stop hurting my brain like that.  So assuming you wanted to store
multiple bits of data, would Sick::Snake look something like:

package Sick::Snake
use Scalar::Util qw 'refaddr';

our @ISA = qw/Angry::Snake/;

my %attr;

sub set_shivering {
    my $snake = shift;
    $attr{refaddr $snake}{shivering} = shift;
    $snake;
}

sub set_sneezing {
    my $snake = shift;
    $attr{refaddr $snake}{sneezing} = shift;
    $snake;
}

sub shivering {...}
sub sneezing {...}

and so on?

That's a very neat trick.  Should I ever be forced to write OO in
Perl, I will try to keep that in mind.  Also, nice plug for
Scalar::Util, which while not quite as nifty as List::Util, is still
one of the more underappreciated modules in Perl, I think.

-=Eric


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

Date: 23 Jul 2005 00:21:40 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: copy contructor
Message-Id: <slrnde33ck.7fo.abigail@alexandra.abigail.nl>

Eric Schwartz (emschwar@pobox.com) wrote on MMMMCCCXLIII September
MCMXCIII in <URL:news:etoy87yxurn.fsf@wilson.emschwar>:
==  Abigail <abigail@abigail.nl> writes:
== > Here's how I would subclass Angry::Snake. Note that I subclass the
== > original Angry::Snake, without requiring it to have an "accessor".
== >
== >     package Angry::Snake;
== >  
== >     sub new {
== >         bless \do {my $c = int rand 5} => shift;
== >     }
== >  
== >     sub poke_it_with_a_stick {
== >         my $snake = shift;
== >         $snake -> attack if $$snake -- < 0;
== >     }
== >  
== >     sub attack { ... }
==  
== <snip rest of example>
==  
==  Ow.  Stop hurting my brain like that.  So assuming you wanted to store
==  multiple bits of data, would Sick::Snake look something like:
==  
==  package Sick::Snake
==  use Scalar::Util qw 'refaddr';
==  
==  our @ISA = qw/Angry::Snake/;
==  
==  my %attr;
==  
==  sub set_shivering {
==      my $snake = shift;
==      $attr{refaddr $snake}{shivering} = shift;
==      $snake;
==  }
==  
==  sub set_sneezing {
==      my $snake = shift;
==      $attr{refaddr $snake}{sneezing} = shift;
==      $snake;
==  }
==  
==  sub shivering {...}
==  sub sneezing {...}


That's one way, but I don't like that (too much typing, and I prefer
to avoid using literal strings for hash keys - using lexical variables
gives you all the power 'use strict' can give you). I do it this way:

    package Sick::Snake; {

        use Scalar::Util qw 'refaddr';
        our @ISA = qw /Angry::Snake/;

        my %shivering;
        my %sneezing;

        sub DESTROY {
            my $snake = shift;
            delete $shivering {refaddr $snake};
            delete $sneezing  {refaddr $snake};
        }

        sub set_shivering {
            my $snake = shift;
            $shivering {refaddr $snake} = shift;
            $snake;
        }
        sub shivering {
            my $snake = shift;
            $shivering {refaddr $snake}
        }

        sub set_sneezing {
            my $snake = shift;
            $sneezing {refaddr $snake} = shift;
            $snake;
        }
        sub sneezing {
            my $snake = shift;
            $sneezing {refaddr $snake}
        }
    }


==  That's a very neat trick.  Should I ever be forced to write OO in
==  Perl, I will try to keep that in mind.  Also, nice plug for
==  Scalar::Util, which while not quite as nifty as List::Util, is still
==  one of the more underappreciated modules in Perl, I think.


I've called this technique 'Inside Out Objects'. Damian Conway promotes
this style in his new book, "Perl Best Practices". He has also written
a module, Class::Std, that takes care of some of the work.



Abigail
-- 
# Perl 5.6.0 broke this.
%0=map{reverse+chop,$_}ABC,ACB,BAC,BCA,CAB,CBA;$_=shift().AC;1while+s/(\d+)((.)
(.))/($0=$1-1)?"$0$3$0{$2}1$2$0$0{$2}$4":"$3 => $4\n"/xeg;print#Towers of Hanoi


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

Date: Fri, 22 Jul 2005 18:47:25 -0600
From: Eric Schwartz <emschwar@pobox.com>
Subject: Re: copy contructor
Message-Id: <etomzoexs9u.fsf@wilson.emschwar>

Abigail <abigail@abigail.nl> writes:
> That's one way, but I don't like that (too much typing, and I prefer
> to avoid using literal strings for hash keys - using lexical variables
> gives you all the power 'use strict' can give you). I do it this way:
>
>     package Sick::Snake; {
>
>         use Scalar::Util qw 'refaddr';
>         our @ISA = qw /Angry::Snake/;
>
>         my %shivering;
>         my %sneezing;

I suppose the only concern I had was that if you have a number of
attributes for an object, this list might become wearying itself to
type.  But then, I suppose you only have to do so once, and anyhow, a
nice comment block to alert the reader that these were attributes
would work fine. It just reminds me of a project I once worked on
where there was a data structure with literally dozens of parallel
arrays (poorly designed, I'll concede), and it was often hard to track
modifications so that they tracked each of these.

>         sub DESTROY {
>             my $snake = shift;
>             delete $shivering {refaddr $snake};
>             delete $sneezing  {refaddr $snake};
>         }

Here in particular, if you aren't careful, you might add an attribute
and forget to put it in DESTROY, whereas my approach would look like:

          sub DESTROY {
              my $snake = shift;
              delete $attrs{refaddr $snake};
          }

But your arguments for lexicals giving the equivalent of use strict is
a strong one, and I don't suppose it's an undue burden to remember to
add a new attribute to DESTROY.  Anyhow, even if you forget, the worst
that would happen is you hold a reference that is inaccessible-- a
memory leak, but not a critical program failure in itself.

-=Eric


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

Date: 23 Jul 2005 01:16:54 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: copy contructor
Message-Id: <slrnde36k6.7fo.abigail@alexandra.abigail.nl>

Eric Schwartz (emschwar@pobox.com) wrote on MMMMCCCXLIV September
MCMXCIII in <URL:news:etomzoexs9u.fsf@wilson.emschwar>:
""  Abigail <abigail@abigail.nl> writes:
"" > That's one way, but I don't like that (too much typing, and I prefer
"" > to avoid using literal strings for hash keys - using lexical variables
"" > gives you all the power 'use strict' can give you). I do it this way:
"" >
"" >     package Sick::Snake; {
"" >
"" >         use Scalar::Util qw 'refaddr';
"" >         our @ISA = qw /Angry::Snake/;
"" >
"" >         my %shivering;
"" >         my %sneezing;
""  
""  I suppose the only concern I had was that if you have a number of
""  attributes for an object, this list might become wearying itself to
""  type.  But then, I suppose you only have to do so once, and anyhow, a
""  nice comment block to alert the reader that these were attributes
""  would work fine. It just reminds me of a project I once worked on
""  where there was a data structure with literally dozens of parallel
""  arrays (poorly designed, I'll concede), and it was often hard to track
""  modifications so that they tracked each of these.
""  
"" >         sub DESTROY {
"" >             my $snake = shift;
"" >             delete $shivering {refaddr $snake};
"" >             delete $sneezing  {refaddr $snake};
"" >         }
""  
""  Here in particular, if you aren't careful, you might add an attribute
""  and forget to put it in DESTROY, whereas my approach would look like:

If you are afraid you forget it, either use Class::Std (and then you
won't even have to create a DESTROY function), or do something like:

    my @attrs = \my (%shivering, %sneezing, ...);

    sub DESTROY {
        my $snake = shift;
        delete $$_ {refaddr $snake} for @attr;
    }

""            sub DESTROY {
""                my $snake = shift;
""                delete $attrs{refaddr $snake};
""            }
""  
""  But your arguments for lexicals giving the equivalent of use strict is
""  a strong one, and I don't suppose it's an undue burden to remember to
""  add a new attribute to DESTROY.  Anyhow, even if you forget, the worst
""  that would happen is you hold a reference that is inaccessible-- a
""  memory leak, but not a critical program failure in itself.


No, the memory leak isn't the worst problem. That's indeed a minor problem.
Not cleaning up attributes has the potential for a program failure though.
Inside-Out object work because every the memory address of every reference
is unique - but the addresses are only unique for the currently existing
references.  If a reference goes out of scope (or rather, the thing it
points to), the memory may be reused, and a new reference might have the
same address as an old one. If you don't clean up your attributes, new
objects may inherit attributes from old, retired, objects.



Abigail
-- 
perl -e '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / 
         % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %;
         BEGIN {% % = ($ _ = " " => print "Just Another Perl Hacker\n")}'


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

Date: Sat, 23 Jul 2005 02:10:52 +0100
From: James Taylor <spam-block-@-SEE-MY-SIG.com>
Subject: Re: Regex (?(?{CODE})) has too many branches
Message-Id: <ant230152dc4fNdQ@riscpc.jtnet>

In article <slrnde2kch.7fo.abigail@alexandra.abigail.nl>,
Abigail <abigail@abigail.nl> wrote:
> 
> James Taylor wrote:
> >  
> > I've never seen a > inside an attribute value that hasn't been
> > converted to a &gt; entity. Wouldn't it would be an error anyway?
> 
> No. You seldomly need to escape an > in HTML. About the only
> time you need to escape an > is in the ]]> token - and there's no
> mainstream browser that can handle <!INCLUDE [ ... [ ... ]]> in a
> meaningful way anyway.

<*whoosh*> That's the sound of that paragraph going way over
my head. I assume that <!INCLUDE> is an SGML thing. Is it
also relevant to HTML? Where can I read up on this?

> > To guard against missing close quotes on attribute values I would
> > prefer to regard the first > as a tag terminator
> 
> So, you're willing to mismatch correctly written HTML in order 
> to deal with incorrectly written HTML?

Well, I'm just trying to match the sophistication of the
solution to the size of the problem and save some complexity
where it isn't needed. It's a case of pragmatism over perfection.
A sledge hammer's great for building railroads, but not
appropriate for cracking nuts. (If you see what I mean.)

> I'd worry more about using whitespace around the equal sign in
> 
>     class="whiteHeading"
> 
> or that single quotes (or no quotes at all) are used.
> Or 'class' in capitals.

Yes, I accept all your concerns, and if I were writing code
for other people to use I'd put more time into making it
work in all circumstances. However, I'm in the lucky position
of writing only for myself and I can rewrite as necessary if
the details of the web page I'm scraping should change.
Indeed, even if I were using a perfect HTML parser, it would
still be impossible to guard against the page format changing
sufficiently to break the seek and scrape code, so I'll have
to monitor it and update it as needed anyway.

> > If commented out portions of HTML become a problem, I can
> > simply strip out the comments before applying the table
> > finding regex under discussion.
> 
> But an attribute might contain '<!--', and another attribute might
> contain '-->'. What's in between is not an HTML comment.

Shocking! It may be legitimate to put unescaped angle brackets
in attribute values but, frankly, anyone who does so is asking
for trouble. Fortunately, I can modify my scrape code as needed,
but others may not have that luxury. Anyone who actually produces
HTML with unescaped angle brackets in unusual places is not
writing robust defensive code and probably deserves what they get.

> Anyway, I'd use something like (untested):
> 
> 
>   m{ <table\b [^"'>]* (?: (?: "[^"]*" | '[^']*' ) [^"']*) * >
>      [^<]* (?: <(?!table) [^<]* )*
>      class="whiteHeading"
>      [^<]* (?: <(?!table) [^<]* )*
>      </table>
>    }xi;

Okay, I tried that but got the following output:

    Fatal signal received: EMT trap
    A core dump will now follow ...

    stack backtrace:

     pc:    d700c sp:    f257c __unixlib_internal_post_signal()
     pc:    66530 sp:    f25bc regcppush()
     pc:    6810c sp:    f2678 regmatch()
     pc:    6810c sp:    f2734 regmatch()
     pc:    6810c sp:    f27f0 regmatch()
     pc:    6810c sp:    f28ac regmatch()
     pc:    6810c sp:    f2968 regmatch()
      .
      .
      .  (Lots more like this)
      .
      .
     pc:    6810c sp:   107b38 regmatch()
     pc:    6810c sp:   107bf4 regmatch()
     pc:    6810c sp:   107cb0 regmatch()
     pc:    6810c sp:   107d6c regmatch()
     pc:    67c64 sp:   107d90 regtry()
     pc:    66ac4 sp:   107e1c Perl_regexec_flags()
     pc:    50644 sp:   107e8c Perl_pp_match()
     pc:    6ab90 sp:   107ea8 Perl_runops_debug()
     pc:    2aebc sp:   107f40 perl_run()
     pc:     81d4 sp:   107f64 main()
     pc:    c21cc sp:   107f80 _main()


Can you tell me what an "EMT trap" is?

I shall have a go at optimizing your regex and putting a few
(?> ... ) wrappers around things to see if that improves things,
but I have a feeling that something more fundamental is awry.

-- 
James Taylor, London, UK                              PGP key: 3FBE1BF9
To protect against spam, the address in the "From:" header is not valid.
In any case, you should reply to the group so that everyone can benefit.
If you must send me a private email, use james at oakseed demon co uk.



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

Date: 23 Jul 2005 01:32:53 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: Regex (?(?{CODE})) has too many branches
Message-Id: <slrnde37i5.7fo.abigail@alexandra.abigail.nl>

James Taylor (spam-block-@-SEE-MY-SIG.com) wrote on MMMMCCCXLIV September
MCMXCIII in <URL:news:ant230152dc4fNdQ@riscpc.jtnet>:
:}  In article <slrnde2kch.7fo.abigail@alexandra.abigail.nl>,
:}  Abigail <abigail@abigail.nl> wrote:
:} > 
:} > James Taylor wrote:
:} > >  
:} > > I've never seen a > inside an attribute value that hasn't been
:} > > converted to a &gt; entity. Wouldn't it would be an error anyway?
:} > 
:} > No. You seldomly need to escape an > in HTML. About the only
:} > time you need to escape an > is in the ]]> token - and there's no
:} > mainstream browser that can handle <!INCLUDE [ ... [ ... ]]> in a
:} > meaningful way anyway.
:}  
:} <*whoosh*> That's the sound of that paragraph going way over
:}  my head. I assume that <!INCLUDE> is an SGML thing. Is it
:}  also relevant to HTML? Where can I read up on this?

Since HTML is an SGML application, anything SGML is relevant to HTML.
Not that 99% of the webauthors or browser programmers care about that
though.

:} > > To guard against missing close quotes on attribute values I would
:} > > prefer to regard the first > as a tag terminator
:} > 
:} > So, you're willing to mismatch correctly written HTML in order 
:} > to deal with incorrectly written HTML?
:}  
:}  Well, I'm just trying to match the sophistication of the
:}  solution to the size of the problem and save some complexity
:}  where it isn't needed. It's a case of pragmatism over perfection.
:}  A sledge hammer's great for building railroads, but not
:}  appropriate for cracking nuts. (If you see what I mean.)

I find it much harder to write a regex for a vague specification
(if you allow for certain kind of errors, it becomes vague), then
for something that is well defined.

In fact, properly defining what you want to match is 95% of writing
your regex.

:} > > If commented out portions of HTML become a problem, I can
:} > > simply strip out the comments before applying the table
:} > > finding regex under discussion.
:} > 
:} > But an attribute might contain '<!--', and another attribute might
:} > contain '-->'. What's in between is not an HTML comment.
:}  
:}  Shocking! It may be legitimate to put unescaped angle brackets
:}  in attribute values but, frankly, anyone who does so is asking
:}  for trouble. Fortunately, I can modify my scrape code as needed,
:}  but others may not have that luxury. Anyone who actually produces
:}  HTML with unescaped angle brackets in unusual places is not
:}  writing robust defensive code and probably deserves what they get.

Huh? They're programming against a rigorously defined standard. And
following it. You can't be more defensive than that.

Anyway, if you want to cut corners, go ahead. Don't expect my sympathy.
Or help. The web is already ruined enough by people with your attitude.


:} > Anyway, I'd use something like (untested):
:} > 
:} > 
:} >   m{ <table\b [^"'>]* (?: (?: "[^"]*" | '[^']*' ) [^"']*) * >
:} >      [^<]* (?: <(?!table) [^<]* )*
:} >      class="whiteHeading"
:} >      [^<]* (?: <(?!table) [^<]* )*
:} >      </table>
:} >    }xi;
:}  
:}  Okay, I tried that but got the following output:
:}  
:}      Fatal signal received: EMT trap
:}  
:}  Can you tell me what an "EMT trap" is?


No. And I don't get a core dump.


:}  I shall have a go at optimizing your regex and putting a few
:}  (?> ... ) wrappers around things to see if that improves things,
:}  but I have a feeling that something more fundamental is awry.



Abigail
-- 
print 74.117.115.116.32;
print 97.110.111.116.104.101.114.32;
print 80.101.114.108.32;
print 72.97.99.107.101.114.10;


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

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
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: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice. 

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 8270
***************************************


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