in reply to Re: using Getopt::Long to modify the default values in new
in thread using Getopt::Long to modify the default values in new
Thanks for your generous comments, Athanasius. This is a good spot for me to repost. Even with edits, it goes on long enough for readmore tags. Output, source, and slightly different questions follow.
$ ./6.MY.translate.pl --configfile C --from tja --infile /home/bob/Doc +uments/meditations/Algorithm-Markov-Multiorder-Learner-master/data/2. +short.shelley.txt --outfile /home/bob/Desktop/1.state input is “The ancient teachers of this science,” said he, “promised impossibilities and performed nothing. The modern masters ... unfold to the world the deepest mysteries of creation. ---------------- begin block to change property is TO type is zilch expected type is zilch did execution get here? property is key type is zilch expected type is zilch did execution get here? property is FROM type is zilch expected type is zilch did execution get here? after block to change, self is bless({ format => 5.23, FROM => "en", key => 321, START => 1562878454, + TO => "ru" }, "My::Module") in new, param_hr is { CONTENT => "\x{201C}The ancient teachers of this science,\x{201D} sa +id he,\n\x{201C}promised impossibilities and performed nothing. The m +odern masters\npromise very little; they know that metals ... the steps\nalready marked, I will pioneer a new way, explore unknown p +owers, and\nunfold to the world the deepest mysteries of creation.\n\ +n", FROM => "tja", key => 123, TO => undef, } in new, self is bless({ format => 5.23, FROM => "en", key => 321, START => 1562878454, + TO => "ru" }, "My::Module") in sub key akey is 123 you called key() method on object 'My::Module=HASH(0x56161e3a1cb0)' key() : changing key to '123' in sub key Use of uninitialized value $akey in concatenation (.) or string at ./6 +.MY.translate.pl line 62. akey is you called key() method on object 'My::Module=HASH(0x56161e3a1cb0)' my key: 123 --- mod is bless({ format => 5.23, FROM => "en", key => 123, START => 1562878454, + TO => "ru" }, "My::Module") $
This is the source that produces that output:
#!/usr/bin/perl -w use 5.011; binmode STDOUT, ":utf8"; use open IN => ':crlf'; use open OUT => ':utf8'; package My::Module; sub new { my ( $class, $param_hr ) = @_; $param_hr = {} unless defined $param_hr; my %self = ( key => 321, format => 5.23, START => time(), 'FROM' => 'en', 'TO' => 'ru', ); say "begin block to change"; use Carp; my $self = \%self; for my $property ( keys %self ) { if ( exists $param_hr->{$property} ) { say "property is $property"; my $type = ref $param_hr->{$property} || 'zilch'; say "type is $type"; my $expected_type = ref $self{$property} || 'zilch'; say "expected type is $expected_type"; croak "$property should be a $expected_type" if $expected_type ne $type; say "did execution get here?"; #$self{$property} = delete $param_hr->{$property}; } } say "after block to change, self is"; bless $self, $class; dd $self; if ( exists $param_hr->{'key'} ) { say "in new, param_hr is"; use Data::Dump; dd $param_hr; say "in new, self is "; dd $self; } if ( exists $param_hr->{'key'} ) { $self->key( $param_hr->{'key'} ) +} else { warn "param 'key' is required."; return undef } return $self; # return hash, now blessed into a class instance, +hallelujah } # get or set the key sub key { say "in sub key"; my $self = $_[0]; my $akey = $_[1]; # optional key say "akey is $akey "; print "you called key() method on object '$self'\n"; if ( defined $akey ) { print "key() : changing key to '$akey'\n"; $self->{'key'} = $akey; } return $self->{'key'}; } 1; package main; use Getopt::Long; my $outfile = undef; my $configfile = undef; my $infile = undef; my $from = undef; my $to = undef; if ( !Getopt::Long::GetOptions( "outfile=s", \$outfile, "infile=s", \$infile, "configfile=s", \$configfile, "from=s", \$from, "to=s", \$to, "help", sub { print "Usage : $0 --configfile C [--outfile O] [--infile I] [--h +elp]\n"; exit 0; }, ) ) { die "error, commandline"; } die "configfile is needed (via --configfile)" unless defined $configfi +le; my $inFH; if ( defined($infile) ) { open( $inFH, '<:crlf:encoding(UTF-8)', $infile ) or die "opening input file $infile, $!"; } my $instr; { local $/ = undef; $instr = <$inFH> } close $inFH; if ( defined($instr) ) { say "input is $instr"; } say "----------------"; # uncomment only if My::Module is in separate file: #use My::Module; my $mod = My::Module->new( { 'key' => 123, 'CONTENT' => $instr, 'FROM' => $from, 'TO' => $to, } ); die unless defined $mod; print "my key: " . $mod->key() . "\n"; say "--- mod is"; dd $mod; __END__
How do the values in new and those from param_hr combine? I think it is supposed to happen in the line that I have commented out in order to get the script to run to termination:
#$self{$property} = delete $param_hr->{$property};The way I read the delete function in perldoc.perl.org listing for delete, the RHS populates the left. If I uncomment that line with things the way they are, then I die more quickly than I want:
---------------- begin block to change property is TO type is zilch expected type is zilch did execution get here? property is key type is zilch expected type is zilch did execution get here? property is FROM type is zilch expected type is zilch did execution get here? after block to change, self is bless({ format => 5.23, FROM => "tja", key => 123, START => 1562881061 +, TO => undef }, "My::Module") param 'key' is required. at ./6.MY.translate.pl line 53. Died at ./6.MY.translate.pl line 133. $
I looked at several sources for references. While interesting, they stevieb's ref tutorial and perl 5.10 ref tut don't provide the explanation I'm looking for. Maybe it's not about ref as much as the ||.
I was thinking that the builtin type for ref was going to include String, but no:
SCALAR ARRAY HASH CODE REF GLOB LVALUE FORMAT IO VSTRING Regexp
So, how do I change this logic so that %self gets the key value pairs from $param_hr? Why does perl take the values from $mod and shunt them into $param_hr via @_ when new is called?
say "begin block to change"; use Carp; my $self = \%self; for my $property ( keys %self ) { if ( exists $param_hr->{$property} ) { say "property is $property"; my $type = ref $param_hr->{$property} || 'zilch'; say "type is $type"; my $expected_type = ref $self{$property} || 'zilch'; say "expected type is $expected_type"; croak "$property should be a $expected_type" if $expected_type ne $type; say "did execution get here?"; $self{$property} = delete $param_hr->{$property}; } } say "after block to change, self is";
Thanks for your comment
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: using Getopt::Long to modify the default values in new
by bliako (Abbot) on Jul 12, 2019 at 10:27 UTC |