LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   How to make a hash of objects in perl (http://www.linuxquestions.org/questions/programming-9/how-to-make-a-hash-of-objects-in-perl-829640/)

Feynman 08-31-2010 10:13 PM

How to make a hash of objects in perl
 
I am trying to make a hash of objects in perl (long story.) I have a package containing the main hash and all the subroutines necessary to work with it. My "new" subroutine used to add an object to the hash goes like this:

Code:

$tmpdir="/tmp";
$subdir="/AutoScript";
$subdir=$tmpdir.$subdir;

%jobs={};

sub new
{
    my $class = shift;
    my $name = shift;
    if(! -d $subdir){mkdir $subdir;}
    $jobs->{ $name } = {
        textfile => shift,
        iofile => '$subdir."/".$name',
        placeholders => {}
    };
    return $jobs->{ $name };
}

The main hash is called $jobs. I call this script from another file that uses the package with this subroutine.
The problem is that only $jobs->{ $name }->{textfile} is accessible to other subroutines. I have tried printing other objects in these subroutines and only the "textfile" object prints a line. The really strange part is that no matter what order I declare those objects, this is always the case!

I give up. PLEASE HELP! I am literally out of ideas. I have spent hours trying every syntax variation and test I can think of.

kbp 08-31-2010 10:27 PM

Looks like you want a hash of hashes,

(untested)

Code:

$tmpdir="/tmp";
$subdir="/AutoScript";
$subdir=$tmpdir.$subdir;

%jobs={};

sub new
{
    my $class = shift;
    my $name = shift;
    if(! -d $subdir){mkdir $subdir;}
    $jobs{ $name => {
        textfile => shift,
        iofile => '$subdir."/".$name',
        placeholders => {}
        }
    };
    return $jobs{ $name };
}


hth

Sergei Steshenko 08-31-2010 10:31 PM

Quote:

Originally Posted by Feynman (Post 4084239)
I am trying to make a hash of objects in perl (long story.) I have a package containing the main hash and all the subroutines necessary to work with it. My "new" subroutine used to add an object to the hash goes like this:

Code:

$tmpdir="/tmp";
$subdir="/AutoScript";
$subdir=$tmpdir.$subdir;

%jobs={};

sub new
{
    my $class = shift;
    my $name = shift;
    if(! -d $subdir){mkdir $subdir;}
    $jobs->{ $name } = {
        textfile => shift,
        iofile => '$subdir."/".$name',
        placeholders => {}
    };
    return $jobs->{ $name };
}

The main hash is called $jobs. I call this script from another file that uses the package with this subroutine.
The problem is that only $jobs->{ $name }->{textfile} is accessible to other subroutines. I have tried printing other objects in these subroutines and only the "textfile" object prints a line. The really strange part is that no matter what order I declare those objects, this is always the case!

I give up. PLEASE HELP! I am literally out of ideas. I have spent hours trying every syntax variation and test I can think of.

  1. How do you call your 'new' ?
  2. Why do you need $class ?
  3. Do you have a package ?
  4. Do you need a package ?
  5. Do your subroutines need anything from global scope, i.e. global variables ?

Meanwhile have a look at the following:

Code:

sergei@amdam2:~/junk/hello_world_in_perl> cat -n sub.prl
    1  use strict;
    2  use warnings;
    3
    4  sub
    5    {
    6    my ($person) = @_;
    7
    8    warn "Hello, $person";
    9    };
sergei@amdam2:~/junk/hello_world_in_perl> cat -n main.pl
    1  #!/usr/bin/perl -w
    2
    3  use strict;
    4  use warnings;
    5
    6  (require './sub.prl')->('10speed705');
sergei@amdam2:~/junk/hello_world_in_perl> ./main.pl
Hello, 10speed705 at ./sub.prl line 8.
sergei@amdam2:~/junk/hello_world_in_perl>


Feynman 08-31-2010 10:36 PM

Come to think of it, it does look like a hash of hashes. That might suit my purposes as well. See, I started out with just objects, but that did not do everything I needed. So I tried to store the objects in a hash and ended up with this code.

As long as I can refer to these "objects" (or keys if I am using a hash) in other subroutines I should be fine.

Anyway, whatever the final product is called, this still is not working and I cannot for the life of me figure out why.

Sergei Steshenko 08-31-2010 10:39 PM

Quote:

Originally Posted by Feynman (Post 4084264)
Come to think of it, it does look like a hash of hashes. That might suit my purposes as well. See, I started out with just objects, but that did not do everything I needed. So I tried to store the objects in a hash and ended up with this code.

As long as I can refer to these "objects" (or keys if I am using a hash) in other subroutines I should be fine.

Anyway, whatever the final product is called, this still is not working and I cannot for the life of me figure out why.

Better give us an example and describe it in plain English. I still do not understand what you mean by "object" here.

Feynman 08-31-2010 10:46 PM

Yes, I do have a package. I call it like this:
use inputgenerator;
inputgenerator->new("test","testtemplate");

or

use inputgenerator;
new inputgenerator("test","testtemplate");

Both fail equally well.

I am pretty sure this is not as simple as forgetting a package because this worked fine before I tried storing the objects in a hash. I just changed the "new" subroutine so it adds to a hash, and I changed how I refer to this new object (or maybe it should be called a hash in this case) in other subroutines to
($class, $name)=@_;
$jobs->{ $name }->{iofile};

I use the $class thing because that was what
http://www.tutorialspoint.com/perl/perl_oo_perl.htm showed me. I admit I do not fully understand the subtlies of the syntax, but it worked before. I would like to say I would learn all the nuts and bolts of what perl is doing, but
a) I have yet to find a description I can understand
b) Although interesting, this is probably more time than it is worth and for now I just would like to be able to understand enough to complete the tasks at hand.

Feynman 08-31-2010 10:47 PM

"object" is easy to describe. It's what these guys call an object:
http://www.tutorialspoint.com/perl/perl_oo_perl.htm

Feynman 08-31-2010 10:53 PM

If you do not think that
http://www.tutorialspoint.com/perl/perl_oo_perl.htm
is the right approach I would not be entirely surprised. Especially since it seems I should not need that "bless" method for this. I am sorry if I confused anyone by not explaining and fully understanding the meaning of "object" in this context. I am trying to find what works. This seemed like what would work, so I used it. I assumed this was a fairly common practice, so I went along using it.

Perhapse a hash of hashes is better. I just need to be able to refer to iofile, placeholders, and name from other subroutines in the same package. That is really it.

Many of my friends do a lot of java programming and they have been lecturing me on the wonders of classes and objects for years now. I thought about their description and figured this fit the description of what I wanted pretty well. Honestly, that is why I was using that approach.

Sergei Steshenko 08-31-2010 10:58 PM

Quote:

Originally Posted by Feynman (Post 4084279)
"object" is easy to describe. It's what these guys call an object:
http://www.tutorialspoint.com/perl/perl_oo_perl.htm

Now that I know what you mean by object:

Quote:

Within Perl, an object is merely a reference to a data type that knows what class it belongs to. The object is stored as a reference in a scalar variable. Because a scalar only contains a reference to the object, the same scalar can hold different objects in different classes.
why do you need objects of such kinds ? Specifically, why do you need a class ?

Further on the way there is "Defining a Class" and later on "Creating and Using Objects" - is your code compliant with what the tutorial says ?

Sergei Steshenko 08-31-2010 11:00 PM

Quote:

Originally Posted by Feynman (Post 4084283)
If you do not think that
http://www.tutorialspoint.com/perl/perl_oo_perl.htm
is the right approach I would not be entirely surprised.
...

I am asking again - why do you need classes and their instances ? And Java people are probably the worst advisers when it comes to Perl - the latter has quite a different spirit.

kbp 08-31-2010 11:04 PM

As a simple helper, try adding 'use warnings;' to your module to show more info

Feynman 08-31-2010 11:07 PM

My code was compliment to what the tutorial says. It worked perfectly before I tried to store the objects in a hash. Now it does not. However, the tutorial never explained how to do such a thing, so there is not much I can go by.

I said earlier--I am not sure I need these "objects" after all. They were the only approach I thought suitable because of conversations with friends that do a lot of programming in java.

Now that I think about it, this is definatly a hash of hashes I am making.

Yes, I need a separate package. I am going to be making many files that use these subroutines and hashes so it is very very nice to have them all stored in one place.

No, no global variables at this point (that I know of). This package uses other packages, but I am not refering to variables from different packages in any package or file. At least not directly (I may make a subroutine that returns the value of some local variable).

Feynman 08-31-2010 11:13 PM

You ask why I need classes and objects--what I need is (forgive me I have never successfully articulated this in any compact manner)
A grouping of "things" (strings and hashes) that are referred to under a common name. For instance thisname(firststring) (or some other syntax with that conveys the same idea of something called "firststring" referred to by/through something else called "thisname") will give me a string.

Tell me if I need to describe my process in more detail. It is rather difficult to completely describe.

Sergei Steshenko 08-31-2010 11:15 PM

Quote:

Originally Posted by Feynman (Post 4084295)
...
Yes, I need a separate package. I am going to be making many files that use these subroutines and hashes so it is very very nice to have them all stored in one place.
...

The statements above does not indicate you need a package, the "one place" can be just a file.

Sergei Steshenko 08-31-2010 11:17 PM

Quote:

Originally Posted by Feynman (Post 4084302)
You ask why I need classes and objects--what I need is (forgive me I have never successfully articulated this in any compact manner)
A grouping of "things" (strings and hashes) that are referred to under a common name. For instance thisname(firststring) (or some other syntax with that conveys the same idea of something called "firststring" referred to by/through something else called "thisname") will give me a string.

Tell me if I need to describe my process in more detail. It is rather difficult to completely describe.

Yes, you need to describe in more detail, and "thisname(firststring)" relationship requires just one level hash:

Code:

my %some_hash =
  (
  name1 => $value1,
  name2 => $value2,
  ...
  nameN => $valueN
  );



All times are GMT -5. The time now is 02:54 PM.