Loading ...
Sorry, an error occurred while loading the content.
 

Re: [PBML] Clear Object's data (long)

Expand Messages
  • Charles K. Clarkson
    In our last exciting episode we created a module and 1 method: Now we ll add the other methods I
    Message 1 of 2 , Apr 27, 2002
      In our last exciting episode we created a module and 1 method:
      <http://groups.yahoo.com/group/perl-beginner/message/9817>

      Now we'll add the other methods I suggested Rob write for this
      module:

      load the objects into a hash with the ids as keys,
      back up the file, <-- This is the one we wrote last time
      write the hash to the file, and
      change/delete any part of the hash.

      We already did the file backup method. Remember a method
      is just a subroutine. Since Rob didn't specify the parameters for
      the file containing the objects he mentioned, we'll make a it up.
      Let's make it simple. Each object will have an id and some text.
      The file will be of this format:

      ID #
      Object Contents
      ID #
      Object Contents
      ID #
      Object Contents

      We'll name this file something creative, like: objects.txt.
      Let's make sure our backup method is still working. When
      we left off last time our first (program) file looked like this:

      #!/usr/bin/perl
      use strict;
      use warnings;

      use lib './modules';
      use object_db;
      my $object = object_db->new;
      print "backup successful\n" if $object->backup('in.txt');

      __END__

      We'll just change the last line to:
      print "backup successful\n" if $object->backup('objects.txt');

      Assuming it works fine, we'll then change it to:
      $object->backup('objects.txt')

      Let's review the module as we left it:

      package object_db;
      use strict;
      use warnings;
      use File::Copy;

      sub new {
      my $this = shift;
      my $class = ref($this) || $this;
      my $self = {};
      bless $self, $class;
      }

      sub backup {
      my $self = shift;
      my $file_name = shift;
      my $backup_name = shift || "$file_name.bak";
      copy( $file_name, $backup_name )
      or die "Cannot make backup: $!";
      return 1;
      }

      1;

      And now we'll write a method for reading the file and
      storing it's contents. Remember we start off a method by
      shifting the object off @_ and we name it $self. You
      don't have to do it this way, but it's the way I will do it
      here:

      sub read {
      my $self = shift;

      Now we'll open the file passed:
      my $file_name = shift;
      open FH, $file_name or die "Cannot open $file_name: $!";

      Then we'll grab the objects:
      chomp( my @objects = <FH> );

      And put them in the object:
      %$self = @objects;
      }

      I'll leave fancy error checking for you to do on your own.
      Let's test it:

      In the program file:
      #!/usr/bin/perl
      use strict;
      use warnings;

      use lib './modules';
      use object_db;
      my $object = object_db->new;
      $object->backup('objects.txt');
      $object->read('objects.txt');
      use Data::Dumper;
      print Dumper $object;

      __END__

      I got:
      $VAR1 = bless( {
      '1' => 'blah',
      '2' => 'blah blah',
      '3' => 'blah blah blah'
      }, 'object_db' );

      with this in my objects.txt file:
      1
      blah
      2
      blah blah
      3
      blah blah blah

      Let's go ahead and write the 'write file' part:

      We'll start out the same:
      sub write {
      my $self = shift;

      We'll open the file passed:
      my $file_name = shift;
      open FH, ">$file_name"
      or die "Cannot open $file_name: $!";

      Then we'll stuff the objects back in the file:
      while ( my ( $id, $value ) = each %$self ) {
      print FH "$id\n$value\n";
      }
      }

      And then we can test it with:
      #!/usr/bin/perl
      use strict;
      use warnings;

      use lib './modules';
      use object_db;
      my $object = object_db->new;
      $object->backup('objects.txt');
      $object->read('objects.txt');
      $object->write('objects.txt');

      Which seems to do everything fine on my system. But
      hold on. How come we have to name the file each time?
      Let's change this behavior to allow us to specify the file
      name when we create the object.
      For a change, we'll write the way want object to
      work, then we'll make it behave that way. Let's make
      'new 'take 1 or 2 file names,. The first name is the file
      we will get our object from (objects.txt). The second,
      optional file name is for a backup file name.
      Here's what we want:

      use object_db;
      my $object = object_db->new('objects.txt');
      $object->backup;
      $object->read;
      $object->write;

      In the module we'll add some code to handle the
      file names sent to the new method. Currently 'new'
      looks like this:

      sub new {
      my $this = shift;
      my $class = ref($this) || $this;
      my $self = {};
      bless $self, $class;
      }

      This can be done a _lot_ of different ways.
      Here's the way I did it:

      sub new {
      my $this = shift;
      my $class = ref($this) || $this;
      my $self = {};
      $self->{file} = $_[0];
      $self->{backup} = $_[1] || "$_[0].bak";
      bless $self, $class;
      }

      Now we need to change the other 3 methods. First,
      is backup:

      sub backup {
      my $self = shift;
      copy( $self->{file}, $self->{backup} )
      or die "Cannot make backup: $!";
      return 1;
      }

      Then read:
      sub read {
      my $self = shift;

      # Now we'll open the file passed:
      open FH, $self->{file}
      or die "Cannot open $self->{file}: $!";

      # Then we'll grab the objects:
      chomp( my @objects = <FH> );
      %$self = @objects;
      }

      But when I tested it I found an error. $self->{file}
      and $self->{backup} disappeared. So I had to change
      the last line:

      From:
      %$self = @objects;

      To:
      %$self =( %$self, @objects);

      Which seems to work just fine.

      And finally, the write method:
      sub write {
      my $self = shift;

      # Now we'll open the file passed:
      open FH, ">$self->{file}"
      or die "Cannot open $self->{file}: $!";

      while ( my ( $id, $value ) = each %$self ) {
      print FH "$id\n$value\n";
      }
      }

      But this also created an error and I had to change
      the 'while' block to test for good $ids:

      while ( my ( $id, $value ) = each %$self ) {
      next if $id =~ /\D/;
      print FH "$id\n$value\n";
      }

      Well, I can see this post has gone long. Next time,
      we'll look at the delete method. Before we stop let's
      recap where we are:

      You should have 4 files:

      ---- object_db.pm ----
      package object_db;
      use strict;
      use warnings;
      use File::Copy;

      sub new {
      my $this = shift;
      my $class = ref($this) || $this;
      my $self = {};
      $self->{file} = $_[0];
      $self->{backup} = $_[1] || "$_[0].bak";
      bless $self, $class;
      }

      sub backup {
      my $self = shift;
      copy( $self->{file}, $self->{backup} )
      or die "Cannot make backup: $!";
      return 1;
      }

      sub read {
      my $self = shift;

      # Now we'll open the file passed:
      open FH, $self->{file}
      or die "Cannot open $self->{file}: $!";

      # Then we'll grab the objects:
      chomp( my @objects = <FH> );
      %$self =( %$self, @objects);
      }

      sub write {
      my $self = shift;

      # Now we'll open the file passed:
      open FH, ">$self->{file}"
      or die "Cannot open $self->{file}: $!";

      while ( my ( $id, $value ) = each %$self ) {
      next if $id =~ /\D/;
      print FH "$id\n$value\n";
      }
      }

      1;
      ---- end object_db.pm ----

      ---- cccc.pl ----
      #!/usr/bin/perl
      use strict;
      use warnings;

      use lib './modules';
      use object_db;
      my $object = object_db->new('objects.txt');
      $object->backup;
      $object->read;
      $object->write;

      # used for testing
      use Data::Dumper;
      print Dumper $object;

      __END__
      ---- end cccc.pl ----

      ---- objects.txt ----
      ---- objects.txt.bak ----
      1
      blah
      2
      blah blah
      3
      blah blah blah

      ---- end objects.txt ----
      ---- end objects.txt.bak ----


      HTH,

      Charles K. Clarkson
      --
      Head Bottle Washer,
      Clarkson Energy Homes, Inc.
      CJ Web Work - Domains for Real Estate Investors.

      E Pluribus Unum -- One from many.


      It is useless for sheep to pass resolutions in favor of vegetarianism while
      wolves remain of a different opinion.
      - W. R. Inge
    Your message has been successfully submitted and would be delivered to recipients shortly.