On Dec 19, 2003, at 8:46 PM, Kenton Brede wrote:
On Thu, Dec 18, 2003 at 12:37:33PM -0800, drieux wrote:
[..]
I've worked with the examples you have shown and I have to admit I'm
just not advanced enough to follow your approach.  I'll ask a few
questions in hopes of getting a little closer to understanding.

Everyone starts someplace... You will forgive me If I push a bit to get folks on down the line a peg. It is the mileage... forgive the sea story,

        once upon a time, the guy who taught me the coolneff of perl5
        would look at stuff that I did in 'sed' and say

looks like line noise to me.

        so I would of course run s2p on it, and he would then stop
        twitiching quite as much, because in perl it was 'readable'.

He of course would come back and ask for really WEIRD stuff,
that he would do in perl, but had to be done in the stock
shell becaue it had to be in a solaris package installer wingnut
thingus and there was no gurantee that perl would be installed,
since this was the package to install perl... So the cosmos
keeps revolving. What looks like 'line noise' one day, is
an 'information stream' on others...

say something on the order of

my ($argv, $options) = parse_cmd_line();

where of course $argv is an array ref and $options is
a hash ref of stuff that will be used in the code.

In the context of my example would $argv and $options be something like $string[0] and $option{version} ?

Sorta - since one can not pass back two 'arrays' one has to pass back an array ref and a hash ref.

hence you would pick them out with

        $argv->[$i]
and
        $option->{$key}

[..]
I don't understand using " print_version('help'); "?  Why not just call
" help_message "?  You have the comment "# tell print-version to call
help and exit"  How by sending the string 'help' in print_version()
is that done?

My presumption is that Since You 'help_message()' has an exit, and by the structure of your original code, the '-v' flag would print the version, and by default fall out, then there needs to be a way to handle

-h -v

which in this case would call

        sub print_version
        {
                my $arg_count = @_; # all we need is the count of them
                                                        # as our boolean.
        
                print "we are version: $VERSION\n"
                help_message() if $arg_count;
                exit(0);
        }

So in the case of JUST the '-v' we just print the version info,
where as in the -h -v, we print the version, THEN call the help_message().



I of course implement your help_message() function with
the ability to take an argument like

        sub help_message
        {
                my ($whiney_msg) = @_;

                print $whiney_msg if $whiney_msg;
                ...
[..]
I don't understand the reason for passing an argument to help_message()
and the reason for the conditionals.

[..]
I probably just don't understand your overall structure.


It is an alternative strategy - there is your by default
behavior help_message() that will assert what ever it is
that should be asserted by definition. But with a $whiney_msg
you can offer up a 'pre-amble' to the basic help message.

eg:
        help_message("Only -v XOR -h\n");

This way your Help information can be tailored to the
foo_bar the primate at the keyboard caused.


Which of course gets me to your


So I could pass the reg_ex like so -


get_record($reg_ex[0]);

actually I would probably be freaky if I have a fixed reg_ex and might do say

get_record(qr/some_pattern_here/);

or if I had done some hash of regExs I might generalize
that to say
        get_records($reg_ex->{$key});


        sub get_record {
                my ($reg_ex, $file ) = @_;

$reg_ex slurps in the value passed to it and $file contains the file passed from below? At least that is what appears to happen when I run the code.

no, the other way around, let's say we are testing this function and we want to run against some other file we might do say

get_record(qr/some_pattern_here/, '/path/to/test_file.txt');

                die "needed a regular expression"
                        unless($reg_ex);

$file ||= "/etc/dhcpd.conf";
              ^^
I've seen || as the or operator but haven't found and example of ||=
yet.  What does that do exactly?

if $file is 'empty' then assign the value.



                 open (DHCPD, $file) ||  die "Can't open $file : $!\n";
                 $/ = '}'; # paragraph delimiter
                 while ( <DHCPD> ) {
                if (m/$reg_ex/i) {print "$_\n\n"};
        }
        close (DHCPD) || die "Error closing /etc/dhcpd $!\n";
        }

This way you move towards reading IN the RegEx that
is passed to the function - and can pass in a 'test file'
for the duration of hacking out the test context...

I don't really understand what you mean here. Are you saying some part of the code above somehow makes the development process easier and then parts should be discarded?


A part of this has to do with scoping and coping.

There are times and places when a sub HAS TO work
with some global parameter not passed to it, sig_handlers
are a classic case of this.

But in general, as a rule of thumb, you should pass
into functions that which the function needs, it should
not have to know anything more about the context it is
in than what YOU tell it. This way functions remain
happy, and can always say,

I was only doing what I was told to do....

allow me to illustrate here

        my ($argv, $options) = parse_cmd_line();
        my $file = $options->{file};

        foreach my $pattern (@$argv)
        {
                get_record($pattern, $file);
        }

since the function get_record() is using what
is passed to it, rather than the hard coded
$string[0] - it sorta 'sings' - what the function
needs to know about doing stuff is based ONLY
on what got passed to it, rather than requiring
the person calling the function to manipulate
stuff and then call the function.

An alternative strategy would be to take the
elements of @$argv and construct a conditional
pattern the old fashion way

        my ($argv, $options) = parse_cmd_line();
        my $file = $options->{file};
        my $pattern = join('|', @$argv);
        get_record($pattern, $file);

now all of a sudden we have moved on to a command line of
the form say

dhcpd_get [-v|-h] [-f alt_file ] element+

where there can be more than one element that one is searching for...

Notice that one's stock "get_record()" will 'just do the right thing'.
The modifications to add the 'file' option are nicely contained
inside the function parse_cmd_line() - and left as an exercise
for the reader...

So that you can feel a tad safer, once upon a time I said
to myself, "I will not write perl line noise stuff, that
will make it harder on the person who has to maintain it...."
Then I had to get a project out and so did the

sub foo { $_[0]->other_method($_[1]) ; }

and I said to myself,

why is the code winking at me ; }



ciao
drieux

---

more demo code to play with

        my ($argv, $options) = parse_cmd_line();
        
        my $file = $options->{file};
        print "no File Passed\n" unless $file;
        
        while( my ($k,$v) = each %$options)
        {
                print "$k -> $v\n";
        }
        
        my $max = scalar(@$argv);
        my $i =0;
        while ( $i < $max )
        {
                print "Hello: " . $argv->[$i++] . "\n";
        }
        
        #------------------------
        #
        sub parse_cmd_line
        {
                my $argcount = @_;
                print "called with $argcount arguments\n";
                my @list = qw/bob ted carol alice/;
                my $option = { foo =>'bar', frodo => 'Bagins' };
                
                ([EMAIL PROTECTED], $option);
                
        } # end of parse_cmd_line


-- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>




Reply via email to