qodeninja
qodeninja

Reputation: 11276

How can I append a string to an array stored in an object, in perl?

I want to use an obj->log($msg) function to store strings, and then later dump them

UPDATED:

use warnings;
use strict;
use diagnostics;
package obj;


  sub log{
      my($self,$log_info) = @_;

      push(@{$self->{log}},$log_info);  

  }

  sub showlog{

    my($self) = @_;
    my $counter = 0;
    my @log= @{$self->{log}};

    print '<div id="log" class="_view _debug"><h1>Log Data</h1>';


        foreach my $i (@log) {
            $counter++;
          print '<div class="item',(($counter%2)?' alt':''),'"><em class="tag">',$counter,'</em><pre>';
          print(Dumper($i));
          print $i;
          print '</pre></div>';
        }
      print '</div>';
  }

but I can't figure out how to append new items to $self->{log} -- I come from PHP land so this is a bit painful.

It would be nice if I could have log be any sort of data, and just dump it out, array, hash or scalar... is there a way to do this?

Upvotes: 0

Views: 714

Answers (5)

Oesor
Oesor

Reputation: 6642

You could use Moose.

package Logger;

use Moose; ### Enables strict/warnings

has '_log_ref' => => (
        traits  => ['Array'],
        is      => 'ro',
        isa     => 'ArrayRef[Str]',
        default => sub { [] },
        handles => {
            _log_contents    => 'elements',
            log              => 'push',
        },
    );

sub showlog {
    my($self) = @_;
    my $counter = 0;

    print '<div id="log" class="_view _debug"><h1>Log Data</h1>';


    for my $i ($self->_log_contents()) {
          $counter++;
          print '<div class="item',(($counter%2)?' alt':''),'"><em class="tag">',$counter,'</em><pre>';
          print(Dumper($i));
          print $i;
          print '</pre></div>';
     }
     print '</div>';
}

Upvotes: 1

Axeman
Axeman

Reputation: 29854

You could useautobox::Core.

use autobox::Core;
...
$self->{log}->push( $log_info );

Upvotes: 1

IanNorton
IanNorton

Reputation: 7282

How about this:

  package Logger;

  # create a logger object
  sub new {
    my ($class) = @_;
    my @messages;

    my $self = {
        log => \@messages,
    };
    bless $self, $class;
    return $self;
  }

  # add a message to the log
  sub append {
    my $self = shift;
    my $message = shift;
    push ( @{$self->{log}}, $message );
  }

  # print the log
  sub printlog {
    my $self = shift;
    foreach my $msg ( @{$self->{log}} ){
      print "$msg\n";
    }
  }

Upvotes: 1

ikegami
ikegami

Reputation: 386396

Hashes values must be scalars. If you want to store multiple values in hash value, you'll need to find a way of placing multiple values in a scalar. A way that would work well here involves storing a reference to an array in the hash value:

$self->{log} = [];  # Optional because of autovivification.

Then place the multiple values in the referenced array:

push @{ $self->{log} }, $log_info;

One would iterate over the values as follows:

for my $entry (@{ $self->{log} }) {

If you want to use index for $i % 2, you can use:

my $log = $self->{log};
for my $i (0..$#$log) {
   my $entry = $log->[$i];
   ...
}

Note: Since 5.14.0,

push $self->{log}, ...;

is mostly equivalent to

push @{ $self->{log} }, ...;

Perl 5.14 is pretty new, so you might want to stay away from that for unless you're just coding for yourself.

Upvotes: 2

user554546
user554546

Reputation:

It appears as though $self->{log} is an array reference. As of Perl 5.14.0, it's safe to push onto array references, but otherwise, you'll want to de-reference the array reference and do: push(@{$self->{log}},$log_info);. Similarly, you'll want to dereference when assigning to @log by doing my @log=@{$self->{log}} (and by the way, you have use strict; and use warnings; at the top of your script, right?).

Take a look at perldoc perlreftut and perldoc perlref.

You'll probably also find Data::Dumper to be handy for printing out complicated data structures. If you want to know everything that's in your log, you can just have use Data::Dumper; at the beginning of your script and then do print Dumper($self->{log}) . "\n"; (no need to de-reference!).

Upvotes: 1

Related Questions