sumedhnarayan has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/bin/perl use warnings; #####***** Defining Required Classes *****#################### +########## package signal; sub _define{ my $type = shift ; my $name = shift ; my $width = shift ; if(($type ne "reg") && ($type ne "wire")) { printf("\n***** ERROR: Wrong Signal type %s\n",$type); exit(1); } my $object = { type => $type , name => $name , width => $width }; bless($object,signal); return $object; } package signal; sub print_defn { my $self = shift; printf("\t%s",$self->{type}); if(($self->{width})!=1) { printf("\t[%d:0]",($self->{width})-1) } else { print(" "); } printf("\t\t\t%s;\n",$self->{name}); } package port; sub _define{ my $direction = shift ; my $name = shift ; my $width = shift ; my $object = { direction => $direction , name => $name , width => $width }; bless($object,port); return $object; } package port; sub print_defn { my $self = shift; printf("\t%s",$self->{direction}); if(($self->{width})!=1) { printf("\t[%d:0]",($self->{width})-1) } else { print(" "); } printf("\t\t\t%s\t\t;\n",$self->{name}); } package connection; sub _define{ my $port = shift ; my $signal = shift ; my $object = { port => $port , signal => $signal }; bless($object,connection); return $object; } package module; sub _define{ my $name = shift; my $object = { name => $name , port_list => () , verilog_list => () , signal_list => () , instance_list => () }; print $object->{port_list}; bless($object,module); return $object; } package module; sub add_port{ my $self = shift ; my $direction = shift ; my $name = shift ; my $width = shift ; my $port = port::_define($direction,$name,$width); push(@{$self{port_list}},$port); } package module; sub add_signal{ my $self = shift ; my $type = shift ; my $name = shift ; my $width = shift ; my $signal = signal::_define($type,$name,$width); push(@{$self{signal_list}},$signal); } package module; sub add_verilog{ my $self = shift ; my $verilog = shift ; push(@{$self{verilog_list}},$verilog); } package module; sub print_defn{ my $self = shift; printf("%s\t(",$self->{name}); foreach my $port (@{$self{port_list}}) { $port->print_defn(); } foreach my $signal (@{$self{signal_list}}) { $signal->print_defn(); } foreach my $verilog (@{$self{verilog_list}}) { #print "verilog\n ${$verilog}"; print $verilog; } my $size=@{$self{port_list}}; print "No of ports $size\n"; } #package instance; # sub _define { # my $module = shift ; # my $name = shift ; # # my $object = { module => $module , # name => $name , # connection_list => [] }; # # #print $module; # #print $object->{module}{port_list}; # $sample = $object->{module}; # print $sample; # $sample =$sample->{port_list}; # print $sample; # #$arraaya= @{$sample}; # #print "here".$arraaya; # #print $sample[4]; # # # $jack=$jack{port_list}; # # $size = @{$jack}; # # # print "size $size"; # # # # #print @{$jack}[4]; # # # # # #foreach $port (@{$object->{module}->{port_list}}){ # foreach $port (@{$sample}){ # print "gere"; # $port->print_defn(); # } # bless($object,instance); # return $object; # # } #package instance; # sub create_empty_connections{ # my $self = shift ; # foreach $port ($self->{module->}){ # # } # } ######***** Main Program *****################################# +########### $module = module::_define('mem','game'); $module->add_port("input","addr",6); $module->add_port("input","WR",6); $module->add_port("input","dd",6); $module->add_port("input","dddr",6); $module->add_signal("wire","a",6); $module->add_signal("wire","b",6); $module->add_signal("wire","b",6); $module->add_signal("wire","d",6); $module->add_signal("reg","e",6); $module->add_signal("reg","e",6); $module->add_signal("reg","e",6); $verilog=" case(cx_state) 1'b0: nx= 1'b1; 1'b1: nx= 1'b0; default: nx= 1'b0; "; $module->add_verilog($verilog); $verilog =" always @(posedge clk) if (!resetn) cx_state <=0 ; else cx_state <= nx ; "; $module->add_verilog($verilog); $module->print_defn(); print "START\n"; $size = @{$module{port_list}}; print "size=".$size."\n"; #use Scalar::Util 'reftype'; #@ref = @{$module->{port_list}}; #$reftype = reftype ($ref); #print $reftype."_ref\n"; print "\n\n\n***END***\n\n\n";

OUTPUT is

[afe_co6] lxcf1:/home/gajbhis/memory > ./n_mw.pl verilog_listmem ( input [5:0] addr + ; input [5:0] WR ; input [5:0] dd ; input [5:0] dddr ; wire [5:0] a; wire [5:0] b; wire [5:0] b; wire [5:0] d; reg [5:0] e; reg [5:0] e; reg [5:0] e; case(cx_state) 1'b0: nx= 1'b1; 1'b1: nx= 1'b0; default: nx= 1'b0; always @(posedge clk) if (!resetn) cx_state <=0 ; else cx_state <= nx ; No of ports 4 START Use of uninitialized value in array dereference at ./n_mw.pl line 232. Use of uninitialized value in concatenation (.) or string at ./n_mw.pl + line 233. size= ***END***

Can you tell me why is this prblem with method and call made outside

Replies are listed 'Best First'.
Re: Problem in accessing array of objects.
by almut (Canon) on Apr 20, 2010 at 09:00 UTC

    I haven't looked through the entire code in detail, but in multiple places you're confusing something like

    $href->{port_list} # correct

    with

    $href{port_list} # incorrect - assumes a hash %href

    (where the $href stands for $module, $self, etc.)

    As the object is a hash reference, you need the arrow here  (you can omit later arrows as in $href->{foo}{bar}, but not the first).

    #!/usr/bin/perl -l use strict; # !!! use warnings; my $module = bless { port_list => [qw(a b c)] }, "Foo"; print "size=", scalar @{$module->{port_list}}; # ok print "size=", scalar @{$module{port_list}}; # not ok!

    without use strict would give

    $ ./835728.pl Name "main::module" used only once: possible typo at ./835728.pl line +9. size=3 Use of uninitialized value $module{"port_list"} in array dereference a +t ./835728.pl line 9. Use of uninitialized value $module{"port_list"} in concatenation (.) o +r string at ./835728.pl line 9. size=

    and with:

    $ ./835728.pl Global symbol "%module" requires explicit package name at ./835728.pl +line 9. Execution of ./835728.pl aborted due to compilation errors.

    Also (though irrelevant to your problem), it's a generally accepted convention to use CamelCase names for normal packages/modules, because all-lowercase names are "reserved" for pragmata (like strict etc.).

Re: Problem in accessing array of objects.
by ReturnOfThelonious (Beadle) on Apr 20, 2010 at 10:25 UTC
    Besides what almut says (emphasis on "use strict;"), your code has a couple of problems. The main one is that you need use square brackets to initialize an array reference. You can't have arrays inside a hash (or hash ref), only references to arrays. So, in function module::_define, you should have:
    my $object = { name => $name , port_list => [] , verilog_list => [] , signal_list => [] , instance_list => [] };
    Also, the "Main program" part of your program is not actually in package 'main' as it should be. It's actually running as part of the initialization of the last package declared, in this case 'module'. That can cause problems. Unless it's declared inside a { } block, a package declaration is in effect in your source code until the next package declaration. You could define package signal like this:
    { package Signal; sub _define{ my $type = shift ; my $name = shift ; my $width = shift ; if(($type ne "reg") && ($type ne "wire")) { printf("\n***** ERROR: Wrong Signal type %s\n",$type); exit(1); } my $object = { type => $type , name => $name , width => $width }; bless($object,__PACKAGE__); return $object; } sub print_defn { my $self = shift; printf("\t%s",$self->{type}); if(($self->{width})!=1) { printf("\t[%d:0]",($self->{width})-1) } else { print(" "); } printf("\t\t\t%s;\n",$self->{name}); } }
    Note the use of the enclosing curly braces. Also, I used __PACKAGE__ in the bless call. I could have also just written bless $object;. If you plan to ever use class inheritance in your program, though, it's better to use the more conventional Perl style which explicitly passes the class as the first argument. You would call Signal->_define($type,$name,$width); instead of Signal::_define($type,$name,$width); and then _define would have another parameter:
    sub _define{ my $class = shift ; my $type = shift ; my $name = shift ; my $width = shift ; if(($type ne "reg") && ($type ne "wire")) { printf("\n***** ERROR: Wrong Signal type %s\n",$type); exit(1); } my $object = { type => $type , name => $name , width => $width }; bless($object, $class); return $object; }