in reply to evolving an OO solution for a bitstream

Frankly, Perl sucks static-variable-wise. They're not directly supported, and must be hacked-over with my() in a BEGIN block. It didn't feel right.

Bah. Heresy. Statics in modules done need a BEGIN block, they dont even need an enclosing scope unless you are being pedantic. And they can be shared amongst any arbitrary set of procedures. So Id say they are pretty powerful actually.

Incidentally you wrote this:

my $stream = BitStream::new("bigbinfile");

Thats not a method call. Thats a procedure call.

Anyway, I whipped this together before I realized that you had already gone down this road. (Really must read nodes a bit more thoroughly before replying :-)

package File::Bitstream; use strict; use warnings; sub new { my ($class,$file)=@_; open my $fh,"<",$file or die "Cant read '$file':$!"; binmode $fh; return bless { file=>$file, fh=>$fh, buffer=>'', chunk=>1024 },$cl +ass; } sub get_bits { my ($self,$bits)=@_; while (!eof($self->{fh}) and length($self->{buffer})<$bits) { my $chars=''; read($self->{fh},$chars,$self->{chunk}); $self->{buffer}.=unpack "B*",$chars; } return length($self->{buffer}) ? substr($self->{buffer},0,$bits,'' +) : undef; } 1; my $o=File::Bitstream->new($0); my $bits=''; print $bits,$/ while defined($bits=$o->get_bits(13));

---
demerphq

    First they ignore you, then they laugh at you, then they fight you, then you win.
    -- Gandhi


Replies are listed 'Best First'.
Re: Re: evolving an OO solution for a bitstream
by spurperl (Priest) on Oct 21, 2003 at 17:39 UTC
    Well, for me shoving procedures into special blocks just for the sake of static variables seems a bit cumbersome.

    You said:

    my $stream = BitStream::new("bigbinfile");
    Thats not a method call. Thats a procedure call.

    I must be missing something. Why isn't Bitstream::new a good way of constructing an object ? Later, I use $stream->get_bits, which is a method call.

      Let's say that BitStream inherits from Stream::Generic. If you call BitStream's new() your way, you cannot do my $self = $class->SUPER::new(@_); to have some intialization deferred to the parent. Better is my $stream = BitStream->new("bigbinfile"); - much easier to extend, now. Plus, you could do something like:
      # This way of dealing with meg and gig is a poor way, used only for de +monstration. # Supersearch for a better way. my $KB = 1024; my $MB = 1024 * $KB; my $GB = 1024 * $MB; my %Classes = ( $MB => 'BitStream::Vec', $GB => 'BitStream::Buffered', ); my $filesize = -s $filename; my $classname = 'BitStream::InMemory'; foreach my $min_size (sort { $a <=> $b } keys %Classes) { last unless $filesize >= $min_size; $classname = $classes{$min_size}; } my $stream = $classname->new($filename);

      That way, you can choose your BitStream::* class based on the size of your file. If it's under a meg, use the instream. Between a meg and a gig, use the hybrid vec option. Over a gig, you need to use the slow buffered method.

      ------
      We are the carpenters and bricklayers of the Information Age.

      The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

      ... strings and arrays will suffice. As they are easily available as native data types in any sane language, ... - blokhead, speaking on evolutionary algorithms

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      Well, for me shoving procedures into special blocks just for the sake of static variables seems a bit cumbersome.

      As compared to what? And does whatever you would compare against allow for statics to be shared amongst a variety of subs? Using the nesting feature of blocks you can set up all kinds of data relationships between subs. (However I admit that I have a Pascal background and nesting subroutines comes naturally.)

      Why isn't Bitstream::new a good way of constructing an object ?

      Because the implementor of Bitsteam might just go and reorganize eveything so that Bitstream doesnt have its own new, but rather inherits it from some other class, perhaps a File::Stream or more realistically IO::File. And then all of a sudden your code breaks. The point is that

      Package::subroutine("is a procedure call which doesn't search \@ISA"); Package->method("is a method call which does search \@ISA");

      I mean, you never know what your other personality is going to do when you aren't looking.
      :-)


      ---
      demerphq

        First they ignore you, then they laugh at you, then they fight you, then you win.
        -- Gandhi


      That should be BitStream->new( 'bigbinfile' ). Now your new() method can be subclassed and is a class method and not just a procedural function.