Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Package problems

by Anonymous Monk
on Apr 14, 2017 at 18:08 UTC ( [id://1187953]=perlquestion: print w/replies, xml ) Need Help??

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

I am learning Perl and I am having a problem with simple packages. The problem is in my second package I can't call the package name of the previous package. Here is my code and also I am using the Perl Padre IDE. Can y'all show me what I am doing wrong when i run the package is shows that it is using the $name from the Cat package and not Dog

package Dog; our $name="Odie"; my $gender = "male"; @treats = ( "table scraps", "pork bone", "bacon twists", "rawhide" ); sub play{ my $dogname = shift; print "$dogname catches a tennis ball.\n"; } package Cat; $name = "Garfield"; print "Treats are : @treats \n"; print "$name says hello to $Dog::name. \n" ; print "$Dog::name is a $Dog::gender. \n" ; print "$name prefers chicken flavored Temptations\n" ; print "$Dog::name loves ",join (" , ", $Dog::treats) , " but prefers $Dog::treats[0]\n" ; Dog::play ($name);

Replies are listed 'Best First'.
Re: Package problems
by shmem (Chancellor) on Apr 14, 2017 at 21:37 UTC
    Can y'all show me what I am doing wrong when i run the package is shows that it is using the $name from the Cat package and not Dog

    Read our.

    package Dog; our $name="Odie";

    Here you are creating an alias of the package variable $Dog::name whose scope goes from there to end of file and spans packages. So, in your package Cat the variable $name also refers to $Dog::name whose value you are overwriting.

    package Dog; our $name = "Odie"; print "dog's name is '$name'\n"; package Cat; $name = 'Garfield'; print "package var \$Cat::name is '$Cat::name'\n"; print "\$name is '$name'\n"; print "package var \$Dog::name is '$Dog::name'\n"; __END__ dog's name is 'Odie' package var $Cat::name is '' $name is 'Garfield' package var $Dog::name is 'Garfield'
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Package problems
by kennethk (Abbot) on Apr 14, 2017 at 22:15 UTC
    Anonymous Monk 2 above is right in the general sense that you probably want to familiarize yourself with a Perl object framework like Moose, but that is not the answer to your question. Likewise, strict would help but does not answer your question (see Use strict warnings and diagnostics or die).

    When you call Dog::play ($name); you are not passing the idea of a variable called $name to Dog::play, but the contents the the variable in current scope. You call Dog::play ($name); in the Cat package, and it has variable called $name. So Perl inserts Garfield into the argument list.

    Of course, this is further confused by your use of our and lack of scope declaration for $name = "Garfield";. If instead you write our $name = "Garfield";, you can now get the two different results by calling

    Dog::play ($Dog::name); # Prints Odie catches a tennis ball.
    or
    Dog::play ($name); # Prints Garfield catches a tennis ball.

    The comments about better methodology would have helped catch and clarify these issues a number of different ways.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Package problems
by Anonymous Monk on Apr 14, 2017 at 18:41 UTC
    You really want something more like this:
    package Animal; use Moo; has [qw(name gender)] => (is => 'ro'); package Pet; use Moo::Role; has [qw(treats pref)] => (is => 'ro'); sub play { sprintf "%s a %s", $_[0]->pref, @{$_[0]->treats}[rand@{$_[0 +]->treats}] } package Dog; use Moo; extends 'Animal'; with 'Pet'; package Cat; use Moo; extends 'Animal'; with 'Pet'; package main; my @pets = ( Dog->new( name => 'Odie', gender => 'male', pref => 'chases', trea +ts => [qw(ball bone doll)] ), Cat->new( name => 'Garfield', gender => 'male', pref => 'eats', tr +eats => [qw(lasagna pookie blanket)] ), ); printf "%s, being %s, %s.\n", $_->name, $_->gender, $_->play for @pets +;
Re: Package problems
by Anonymous Monk on Apr 14, 2017 at 18:16 UTC
    package Dog; our $name="Odie"; our $gender = "male"; @treats = ( "lasaggnah", "3 cheese pizzas", "taco shells", "BRAAPP" ); sub play{ my $dogname = shift; print "$dogname catches a tennis ball.\n"; } package Cat; my $name = "Garmfield"; print "Treats are : @Dog::treats \n"; print "$name says hello to $Dog::name. \n" ; print "$Dog::name is a $Dog::gender. \n" ; print "$name prefers kicking $Dog::name.\n" ; print "$Dog::name loves ",join (" , ", @Dog::treats) , " but prefers $Dog::treats[0]\n" ; Dog::play ($name);
Re: Package problems
by Anonymous Monk on Apr 14, 2017 at 20:55 UTC
    The problem is that you are using our in one place and not the other. Either use our in both packages, or don't use it in either. Or put brackets around the package contents, like this:
    package Dog { our $name="Odie"; } package Cat { $name = "Garfield"; print "$name says hello to $Dog::name. \n" ; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1187953]
Approved by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-24 04:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found