develooper Front page | perl.perl5.porters | Postings from August 2008

Re: Fighting the Good Fight against spam deluge (was: Senatorial (Senescent?) reflective pause)

From:
jvromans
Date:
August 1, 2008 03:29
Subject:
Re: Fighting the Good Fight against spam deluge (was: Senatorial (Senescent?) reflective pause)
Message ID:
18578.58721.180685.719191@phoenix.squirrel.nl
[Quoting Tom Christiansen, on July 31 2008, 16:15, in "Fighting the Good Fi"]
> In-Reply-To: Message from Johan Vromans <jvromans@squirrel.nl> 
> > I'd go for a nice iterator class instead of <<<<>>>> weirdness.
> 
> But now I'm curious--a condition for which, per Dorothy Parker, there
> is no cure :).  Still, I'll try to cure it by asking whether you
> might you mean:
> 
> (1) A class that has some sort of:
> 
>     use overload "<>" => sub { ... };

Basically, yes.

=head1 NAME

Iterator::Diamond - Iterate through the files from ARGV

=head1 VERSION

Version 0.01

=head1 SYNOPSIS

Iterator::Diamond provides a safe and customizable replacement for the
C<< <> >> (Diamond) operator.

Just like C<< <> >> it returns the records of all files specified in
C<@ARGV>, one by one, as if it were one big happy file. In-place
editing of files is also supported. It does use C<@ARGV>, C<$ARGV> and
C<ARGVOUT> as documented in L<perlrun>.

As opposed to the built-in C<< <> >> operator, no magic is applied to
the file names unless explicitly requested. This means that you're
protected from file names that may wreak havoc to your system when
processed through the magic of the two-argument open() that Perl
normally uses for C<< <> >>.

Examples:

    use Iterator::Diamond;

    $input = Iterator::Diamond->new();
    while ( $input->has_next ) {
        $line = $input->next;
        ...
    }

    while ( <$input> ) {
        ...
    }

    use Iterator::Diamond qw(overload);

    while ( <> ) {
        ...
    }

=head1 FUNCTIONS

=head2 new

Constructor. Creates a new iterator.

The iterator can be used by calling its methods, but it can also be
used as argument to the readline operator. See the examples in
L<SYNOPSIS>.

B<new> takes an optional series of key/value pairs to control the
exact way the iterator must behave.

=over 4

=item B<< magic => >> { none | stdin | all }

C<none> applies three-argument open semantics to all file names and do
not use any magic. This is the default behaviour.

C<stdin> is also safe. It applies three-argument open semantics but
allows a file name consisting of a single dash C<< - >> to mean the
standard input of the program. This is often very convenient.

C<all> applies two-argument open semantics. This makes the iteration
unsafe again, just like the built-in C<< <> >> operator.

=item B<< edit => >> I<suffix>

Enables in-place editing of files, just as the built-in C<< <> >> operator.

Using the perl command line option C<-I>I<suffix> has the same effect.

=back

=head2 next

Method, no arguments.

Returns the next record of the input stream, or undef if the stream is
exhausted.

=head2 has_next

Method, no arguments.

Returns true if the stream is not exhausted. A subsequent call to
C<next> will return a defined value.

=head2 is_eof

Method, no arguments.

Returns true if the current file is exhausted. A subsequent call to
C<next> will open the next file if available and start reading it.

=head2 current_file

Method, no arguments.

Returns the name of the current file being processed.

=head1 GLOBAL VARIABLES

Since Iterator::Diamond is a plug-in replacement for the built-in C<<
<> >> operator, it uses the same global variables as C<< <> >> for the
same purposes.

=over 4

=item @ARGV

The list of file names to be processed. When a new file is opened, its
name is removed from the list.

=item $ARGV

The name of the file currently being processed. This can be more
elegantly obtained by using the iterators C<current_file> method.

=item $^I

Enables in-place editing and, optionally, designates the backup suffix
for edited files. See L<perlrun> for details.

Setting C<$^I> to I<suffix> has the same effect as using the Perl
command line argument C<-I>I<suffix> or using the C<edit=>I<suffix>
option to the iterator constructor.

=item ARGVOUT

When in-place editing, this file handle is used to open the new,
possibly modified, file to be written. This file handle is select()ed
for standard output.

=back

=head1 ACKNOWLEDGEMENTS

This modules was inspired by a most interesting discussion of the
perl5-porters mailing list, July 2008, on the topic of the unsafeness
of two-argument open() and its use in the C<< <> >> operator.

=cut

-- Johan



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About