Using @ARGV in object oriented script

J

Jorge

As an exercise in learing Object Oriented Perl I am creating a class
and a calling script which simply checks the command line arguments to
see if each file is present. So far it appears to be working as
expected but I have a question about the use of @ARGV in my calling
script.

The only way I could see to pass @ARGV as an object was to make it a
scalar ... thus the line ...

my $list_of_files = join ' ', @ARGV;

Is there a way I can use a reference such as \@ARGV and somehow
derference it in the package?

Both my script and package is listed below -- I appreciate any help on
this - thank you.


snip<------ package starts here ------>snip

#!/usr/local/bin/perl -w

package CmdLineArgs;

use strict;

sub new {
my $cla = {};
$cla->{QTY} = undef;
$cla->{LIST} = [];
bless($cla);
return $cla;
}

sub qty {
my $cla = shift;
if (@_) { $cla->{QTY} = shift }
return $cla->{QTY};
}

sub list {
my(@args, $args, @args_not_found);
my $cla = shift;

if (@_) { $cla->{LIST} = shift }

@args = split(' ', $cla->{LIST} );
foreach $args(@args){
if(!( -f $args)){
push(@args_not_found, $args);
}
}

if(@args_not_found){
return @args_not_found;
}else{
return "success";
}
}

1;

snip<------ calling script starts here ------>snip

#!/usr/local/bin/perl -w

use strict;

use lib '/home/blahblah/lib';

use CmdLineArgs;

my $args;

$args = CmdLineArgs->new();

$args->qty($#ARGV + 1);

my $list_of_files = join ' ', @ARGV;

print "\n".$args->qty." files were specified as command line arguments
\n";
print "(".$list_of_files.")\n";

if($args->list($list_of_files) eq "success"){
print $args->list($list_of_files)."\n";
}else{
my @not_found = $args->list($list_of_files);
foreach my $not_found(@not_found){
print $not_found." - was not found\n";
}
}
 
K

Klaus

As an exercise in learing Object Oriented Perl I am creating a class
and a calling script which simply checks the command line arguments to
see if each file is present. So far it appears to be working as
expected but I have a question about the use of @ARGV in my calling
script.

The only way I could see to pass @ARGV as an object was to make it a
scalar ... thus the line ...

my $list_of_files = join ' ', @ARGV;

Is there a way I can use a reference such as \@ARGV and somehow
derference it in the package?

I am not so familiar with object-oriented programming, but
dereferencing \@ARGV in a simple subroutine should work the same way:

====================================================
use strict;
use warnings;

print do{ local $" = "', '"; "Before sub test(): \@ARGV = ('@ARGV')
\n"; };

test_ARGV(\@ARGV);

print "Test program finished.\n";

sub test_ARGV {
my @Array = @{$_[0]};
print do{ local $" = "', '"; "Inside sub test(): \@Array =
('@Array')\n"; }
}
====================================================

C:\>perl Ref-ARGV.pl a b c
Before sub test(): @ARGV = ('a', 'b', 'c')
Inside sub test(): @Array = ('a', 'b', 'c')
Test program finished.
 
B

Ben Morrow

Quoth "Klaus said:
I am not so familiar with object-oriented programming, but
dereferencing \@ARGV in a simple subroutine should work the same way:

Methods work exactly the same as subs once they have been called. The
only difference is in how the method is located and called.
====================================================
use strict;
use warnings;

print do{ local $" = "', '"; "Before sub test(): \@ARGV = ('@ARGV')
\n"; };

I realise this is not the point of your post :), but this is
unnecessarily ugly. Since it's only a tiny program, just set $" and have
done:

$" = "', '";
warn "Before sub test(): \@ARGV = ('@ARGV')";

You could probably omit the 'Before sub test()' as well: the line number
given by warn is clear enough, or use Carp::cluck.
test_ARGV(\@ARGV);

print "Test program finished.\n";

sub test_ARGV {
my @Array = @{$_[0]};

I don't know if you realise, but this makes a *copy* of the passed in
array. With large arrays, or if you are wanting to modify the array
in-place, you want something more like

my ($Array) = @_;
warn "\@Array = ('@$Array')";
print do{ local $" = "', '"; "Inside sub test(): \@Array =
('@Array')\n"; }
}

Ben
 
J

Jorge

As an exercise in learing Object Oriented Perl I am creating a class
and a calling script which simply checks the command line arguments to
see if each file is present. So far it appears to be working as
expected but I have a question about the use of @ARGV in my calling
script.

OO is a programming technique with some charachteristics and possible
advantages. @ARGV is an array. The two things are completely
orthogonal, well at least in Perl 5 since we normally do not have
autoboxing (i.e. not everything is an object by default) unless you
use a specific module, which is an aftertought anyway.
The only way I could see to pass @ARGV as an object was to make it a
scalar ... thus the line ...

To "pass @ARGV as an object" does not make sense at all. You can pass
@ARGV to an object or class method as a parameter, in wich case it
will be flattened to a list. If you want to keep its "arrayedness",
just take a reference \@ARGV, or build a new one for the purpose
[@ARGV].
my $list_of_files = join ' ', @ARGV;

Awful! First of all, are all of @ARGV's elemnts filenames? And what if
any of them contsains a whitespace?
Is there a way I can use a reference such as \@ARGV and somehow
derference it in the package?

Yes, just like you would dereference it in any Perl program, OO or
not:

perldoc perlref

Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
.'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Point taken on nearly all the replies. Being in a learing stage of
OOP, I find it very helpful.

Thank You
 
K

Klaus

I realise this is not the point of your post :), but this is
unnecessarily ugly. Since it's only a tiny program, just set $" and have
done:

$" = "', '";
warn "Before sub test(): \@ARGV = ('@ARGV')";

I was in the habit of always localising $"
(see perldoc perlvar : "[...] In most cases you want to localize these
variables before changing them [...]")

But I agree with you, localising $" in this simple example is
overkill.
test_ARGV(\@ARGV);
print "Test program finished.\n";
sub test_ARGV {
my @Array = @{$_[0]};

I don't know if you realise, but this makes a *copy* of the passed in
array. With large arrays, or if you are wanting to modify the array
in-place, you want something more like

my ($Array) = @_;
warn "\@Array = ('@$Array')";
print do{ local $" = "', '"; "Inside sub test(): \@Array =
('@Array')\n"; }
}

Point taken. Thanks for the hint.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top