f



use a hash from a module within a main program without passing by reference or value

Hello,

i have a module and my program that uses it.
i want to use the hash which is only declared
in my module within the main program.
I want the output to be
one
two
two
one

but it prints nothing
anyone can help me out and teach me the
scope of variables when using modules?
in other words: how can i make %MYCOOLHASH
available in test.pl without passing it by reference
or value.

thanks in advance
Sebastian

--- test.pl ------------------
use mycoolmodule;

print "$MYCOOLHASH{'test1'}\n";
print "$MYCOOLHASH{'test2'}\n";
&changeValues();
print "$MYCOOLHASH{'test1'}\n";
print "$MYCOOLHASH{'test2'}\n";
exit;
----------------------------------------

--- mycoolmodule.pm ------------------

my %MYCOOLHASH;
$MYCOOLHASH{'test1'} = "one";
$MYCOOLHASH{'test2'} = "two";

sub changeValues
{
$MYCOOLHASH{'test1'} = "two";
$MYCOOLHASH('test2'} = "one";
}
1;
exit;
----------------------------------------


0
Sebastian
3/7/2005 6:47:35 PM
comp.lang.perl.misc 33233 articles. 2 followers. brian (1246) is leader. Post Follow

4 Replies
431 Views

Similar Articles

[PageSpeed] 56

Sebastian Marants wrote:
>
> i have a module and my program that uses it.
> i want to use the hash which is only declared
> in my module within the main program.
> I want the output to be
> one
> two
> two
> one
>
> but it prints nothing
>
> --- test.pl ------------------
> use mycoolmodule;
>
> print "$MYCOOLHASH{'test1'}\n";
> print "$MYCOOLHASH{'test2'}\n";
> &changeValues();
> print "$MYCOOLHASH{'test1'}\n";
> print "$MYCOOLHASH{'test2'}\n";
> exit;
> ----------------------------------------
>
> --- mycoolmodule.pm ------------------
>
> my %MYCOOLHASH;
> $MYCOOLHASH{'test1'} = "one";
> $MYCOOLHASH{'test2'} = "two";
>
> sub changeValues
> {
> $MYCOOLHASH{'test1'} = "two";
> $MYCOOLHASH('test2'} = "one";
> }
> 1;
> exit;
> ----------------------------------------


Dear Sebastian,

   Try declaring %MYCOOLHASH with "our" instead of "my".  Using "my"
makes %MYCOOLHASH accessible only to the "mycoolmodule.pm" file,
whereas using "our" makes it accessible to the entire "main" package.

   I also recommend using "use strict;" and "use warnings;".  If you
had used them, they would have let you know that %MYCOOLHASH did not
exist in the "test.pl" file.

   I hope this helps, Sebastian.

   -- Jean-Luc Romano

0
jl_post
3/7/2005 7:57:39 PM
"Sebastian Marants" <semura@gmx.de> writes:
> i have a module and my program that uses it.
> i want to use the hash which is only declared
> in my module within the main program.
> I want the output to be
> one
> two
> two
> one
>
> but it prints nothing
> anyone can help me out and teach me the
> scope of variables when using modules?

In this case, it's no different than the scope of anything else.  'my'
variables are lexically scoped, and therefore not accessible from
outside your module.  'perldoc -f my' to read more about this.

> in other words: how can i make %MYCOOLHASH
> available in test.pl without passing it by reference
> or value.

As a general principle, You Don't Want To Do This(tm).  There are a
few places where global variables are required, but almost every place
they're used, they're not needed.  In this case, I would probably use
an accessor and a setter function, which I will explain below.


> --- test.pl ------------------
> use mycoolmodule;

use warnings;
use strict;

> print "$MYCOOLHASH{'test1'}\n";
> print "$MYCOOLHASH{'test2'}\n";

print GetHashVal('test1');
print GetHashVal('test2');

> &changeValues();

You don't want to call functions with & unless you know what it does
and why.  I will bet your next paycheck that you don't.  This isn't a
crime, so just educate yourself by reading 'perldoc perlsub'.

> print "$MYCOOLHASH{'test1'}\n";
> print "$MYCOOLHASH{'test2'}\n";

See above.  Also, all-upper-case names read as if you're shouting, and
are by convention reserved for constants in Perl.  This clearly isn't
a constant, since you're changing it, so perhaps

%my_cool_hash

would be better here.

> exit;
> ----------------------------------------
>
> --- mycoolmodule.pm ------------------
>
> my %MYCOOLHASH;
> $MYCOOLHASH{'test1'} = "one";
> $MYCOOLHASH{'test2'} = "two";
>
> sub changeValues
> {
> $MYCOOLHASH{'test1'} = "two";
> $MYCOOLHASH('test2'} = "one";
> }

In general, I'd avoid making global variables here, too.

Maybe something like:

our %MYCOOLHASH;

sub changeValues
{
   my (%hash) = @_;

   $hash{test1} = 'two';
   $hash{test2} = 'one';

   return %hash;
}

Then you could do in your main program:

%MYCOOLHASH = changeValues(%MYCOOLHASH);

or even

%my_switched_hash = changeValues(%my_cool_hash);

in case you want to save the original to compare the switched one with
later.

> 1;
> exit;

This can't be your real code; this exit here will cause your main
program to exit as soon as it is encountered.  Please cut and paste
real code.

-=Eric
-- 
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
		-- Blair Houghton.
0
Eric
3/7/2005 8:09:42 PM
"Sebastian Marants" <semura@gmx.de> wrote:
> Hello,
>
> i have a module and my program that uses it.
> i want to use the hash which is only declared
> in my module within the main program.

Why?  If you want to do this, it often means that you
haven't designed your module boundaries very well.


> I want the output to be
> one
> two
> two
> one
>
> but it prints nothing

I bet it prints *something*.

> anyone can help me out and teach me the
> scope of variables when using modules?

The docs can probably teach you that.  If you read
the apparently relevant docs and still don't know, it would be best
if you tell us that in your post.

See:

perldoc -f my
perldoc perlsub
perldoc perlmod

And, because the answer to your question (other than "don't do that")
is to use package rather than lexical variables, you should probably
also see:

perldoc -f our

-- 
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service                        $9.95/Month 30GB
0
xhoster
3/7/2005 8:54:20 PM
In: <d0i7mp$56d$1@beech.fernuni-hagen.de>, "Sebastian Marants" <semura@gmx.de> wrote:
>Hello,
>
>i have a module and my program that uses it.
>i want to use the hash which is only declared
>in my module within the main program.
>I want the output to be
>one
>two
>two
>one
>
>but it prints nothing
>anyone can help me out and teach me the
>scope of variables when using modules?
>in other words: how can i make %MYCOOLHASH
>available in test.pl without passing it by reference
>or value.

Well... as everyone else pointed out, don't. :-)

If we're going to do it anyway, you could use Exporter to export the symbol
into the callers name space. Don't bother with @EXPORT_OK, just go ahead and
cram it into the callers namespace if pollution is the goal. 

If we're going to do ticky-tacky things, we could use a glob to create an
'alias' (well sort of):

local(*bogus) = \%mycoolmodule::MYCOOLHASH;

$bogus{test1} = "puke";

Or, you could access it from anywhere by simply accessing it:

$mycoolmodule::MYCOOLHASH{test1} = 'home invader!';

I actually perfer this for global variables, since it makes clear what we're
doing w/out actually contaminating other name spaces. (Some folks might
disagree with me) of course, accessors and all that stuff are better, but if
you have a real reason for getting at the global variable, absolute addressing
works. (has the disadvantage that if you rename your module, you're kind of
screwed)

Finally, have a look at perltie, 'mycoolmodule' (might I suggest camel caps to
distinguish it from perl pragma's?) 

In essence, with tie, your module can *be* the hash. This is how the DBM's do
it. You get to treat it like a hash, but you get the setter/getter pattern. 

In your case, using a static global variable, a tied hash will provide hours of
entertainment to anyone trying to figure out why setting the value of one hash
impacts any other tied hashes they may have. 

Jamie
-- 
http://www.geniegate.com                    Custom web programming
guhzo_42@lnubb.pbz (rot13)                User Management Solutions
0
nospam
3/9/2005 4:56:38 AM
Reply: