user621092
user621092

Reputation: 51

Moose basics: open file and parse

I am new to Moose and OOP and would like some guidance on solving a very basic file handling and parsing requirement using Moose. I am familiar with Perl, and would like to start using OOP.

Essentially, all that I want to do is open a text file, parse it, and print to stdout.

For instance using standard Perl

open (FILE , input.txt);
while (FILE)
{
  if (/(\S+)\s+(\d+)/)
  {
    print "$1-$2";
  }
}

where input.txt is

ABC 20
DEF 10
GHI 50

Upvotes: 1

Views: 1049

Answers (4)

Borodin
Borodin

Reputation: 126722

This is a very simple Perl program and using Moose would only complicate it.

Before you progress to writing object-oriented Perl

  • Always use strict and use warnings at the start of your program
  • Use lexical filehandles, the three-argument form of open and always check the success of every open call
use strict;
use warnings;

open my $fh, '<', 'input.txt' or die $!;

/(\S+)\s+(\d+)/ and print "$1-$2\n" while <$fh>;

Upvotes: 0

Ether
Ether

Reputation: 53976

Opening files doesn't really relate to Moose in any way. However, if you are looking for existing interfaces to deal with files, you should take a look at Path::Class::File, which is an object that will contain a filename and provide you many methods for dealing with the file it represents. It is quite common to use this class as a Moose type constraint in an attribute:

package MyApp::Foo;

use Moose;

has filename => (
    is => 'ro', isa => 'Path::Class::File',
);

sub process_file
{
    my $this = shift;

    if (-e $this->filename)
    {
        my $fh = $this->filename->openr;
        while (my $line = <$fh>)
        {
             # process file, line by line...
        }
    }
}

package main;

my $obj = MyApp::Foo->new(filename => '/home/me/foo.txt');
$obj->process_file;

You could also modify the process_file method so it takes a coderef which receives one line from the file as an argument, to process the file contents in a more modular way. It all depends on what you need your program to do, of course.

Alternatively, if you like MooseX::Types, you can do:

use MooseX::Types::Path::Class qw(Dir File);
has file => ( ..., isa => File, coerce => 1, ... );

This will let you pass a filename to the attribute and it will automatically inflate into a Path::Class::File object internally.

Upvotes: 4

bvr
bvr

Reputation: 9697

Based on comment under DVK's answer, you might be asking for something like this?

package CORDx;
use Moose;
use Carp;

sub parse_log {
    my ($self,$input_name, $whatever) = @_;
    open my $fh, "<", $input_name
        or croak "\"$input_name\" not found";

    while(<$fh>) {
        if(/(\S+)\s+(\d+)/) {
            print "$1-$2";
        }
    }
}


package main;
use CORDx;

my $cordr = CORDx->new();
$cordr->parse_log('input.txt');

Upvotes: 0

DVK
DVK

Reputation: 129413

You might want to try emulating examples in Moose::Cookbook.

To be honest, your own example is not really OOP related.

If you mean using OOP version of IO, you can easily do that (use IO::Handle) module, but that module is not Moose based.

If you mean you want to wrap the file code above into a Moose-based module, you certainly can but you need to clarify the (Moose-independent) OOP design you want. E.g. what are the instance variables you seek? methods?

Upvotes: 1

Related Questions