LinuxQuestions.org

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

Feynman 08-31-2010 10:43 PM

Ok, for starters, this is the same project I have been working on since I started posting on this website. I want to be able to read a template, replace specified strings with values defined as the arguments of some subroutine, and then print the output to a new file. Then I want to pass the new file to an other program that generates an output file. Then I want to parse the output file and extract useful numbers and tables. Then I want to have the ability of sending those to another template file or some other subroutine, or simply print them out on the screen.

I decided it would be almost essential to have all the files that result from one template file (the input and output files) in one directory. So, my first thought was, "all my friends use these classes and objects, perhaps I could define a class that has the path to the template file, all the strings to look for, and all the corresponding values they should be replaced with as objects." That seemed like a good solution until I needed to make a unique directory for the files. I thought about using PID, but what if my code made a bunch of such class members (i.e. processed several template files and looked at data found in several of the corresponding output files)? Then, in theory, the PID could be recycled and used for more than one of these template processing procedures. But whether that is true or not (this was just a concern I had), I realized the perfect solution was to create a directory named after the object that contained the template file. I posted on stackoverflow about this, and they all said this was nearly impossible in perl and my approach was probably wrong. One of them suggested a hash of objects. I had learned about hashes by now (as I used them to store strings to look for = values to replace them with) and I had used hashes of hashes of hashes already (this is actually slightly more complicated than I explained, but this is getting long enough). I had actually considered this and after that suggestion I decided this must be the best approach.

And that brings me here...

Feynman 08-31-2010 10:50 PM

You said my statement did not indicate the need for a package and a file would do. I did not know that. Can I use subroutines stored in another file without making it a package? If so--and you think this is better--I see no reason why not.

Sergei Steshenko 08-31-2010 10:53 PM

Quote:

Originally Posted by Feynman (Post 4084328)
You said my statement did not indicate the need for a package and a file would do. I did not know that. Can I use subroutines stored in another file without making it a package? If so--and you think this is better--I see no reason why not.

Yes, you can.

Try to understand my example in http://www.linuxquestions.org/questi...0/#post4084259 post - the point is that a reference can be exported by one file and imported by another.

After that we'll talk how to extend the example to multiple subroutines. Or you decide you actually like the idea to store one subroutine per file.

Feynman 08-31-2010 10:56 PM

Ok thank you. I will get back to you tomorrow. It is getting late.

Sergei Steshenko 08-31-2010 10:59 PM

Quote:

Originally Posted by Feynman (Post 4084333)
Ok thank you. I will get back to you tomorrow. It is getting late.

OK; also think that a filesystem directory is a natural container of residing in it files, and the directory name may reflect commonality of the files functionality. It's WRT to storing one subroutine per file.

Feynman 09-01-2010 10:24 AM

Ok, I did your example and I see your point. It still seems to me like a waste of a perl file to just store one subroutine there--not to mention extra writing for each line of code when it is referred to.

In short, I still think the best approach is to have one file with all the subroutines needed make input files from templates. There really are not that many--they just require some thought in coding. This way I have them all stored in one place--and I do not have to keep saying "require." This would make working with a few dozen templates much easier. Granted, I may not get to this point, but in theory working with over a dozen template files at once would seem quite reasonable for doing thorough investigations of large molecules (again, I am using this program to run input files containing information about molecules on quantum chemistry software that calculates properties of said molecules.)

This way, whenever I am working on a new job with molecules, all I have to do is say "use inputgenerator" and I have all the subroutines necessary to make my input files. I will later get to the point where I say "use generalparsers" and I will have all the subroutines I need to parse the output files.

Sergei Steshenko 09-01-2010 12:39 PM

Quote:

Originally Posted by Feynman (Post 4084940)
Ok, I did your example and I see your point. It still seems to me like a waste of a perl file to just store one subroutine there--not to mention extra writing for each line of code when it is referred to.

In short, I still think the best approach is to have one file with all the subroutines needed make input files from templates. There really are not that many--they just require some thought in coding. This way I have them all stored in one place--and I do not have to keep saying "require." This would make working with a few dozen templates much easier. Granted, I may not get to this point, but in theory working with over a dozen template files at once would seem quite reasonable for doing thorough investigations of large molecules (again, I am using this program to run input files containing information about molecules on quantum chemistry software that calculates properties of said molecules.)

This way, whenever I am working on a new job with molecules, all I have to do is say "use inputgenerator" and I have all the subroutines necessary to make my input files. I will later get to the point where I say "use generalparsers" and I will have all the subroutines I need to parse the output files.

You do not have to keep saying "require" - Perl has 'opendir', 'readdir', and the latter is normally called in a loop. So 'require' will appear once in the loop body.

Another point of my code example is that the exported reference is anonymous. I.e. since it has no name, it by definition can't conflict with any other name - unlike traditional named subroutine.

The fundamental idea with anonymous references is that they get name (if any) in the places where they are used, not in the place where the object (in English sense) they point to is defined/described.

Feynman 09-01-2010 03:38 PM

Here is what I typed in:

use strict;
use warnings;

require 'sub.pl';
'sub.pl'->('10speed705');

and an error came up. How do I only say "require" once?

Sergei Steshenko 09-01-2010 03:48 PM

Quote:

Originally Posted by Feynman (Post 4085279)
Here is what I typed in:

use strict;
use warnings;

require 'sub.pl';
'sub.pl'->('10speed705');

and an error came up. How do I only say "require" once?

How about first publishing all the sources, i.e. the source of 'sub.pl' ?

Is there a reason for changing my code ?

Feynman 09-01-2010 04:01 PM

I was trying to use require only once. You said that was possible. I had also tried:
use strict;
use warnings;

(require 'sub.pl')->('10speed705');
('sub.pl')->('10speed705');

which did not work either. I managed to get my hash of hashes working. I have it as a package. I will change it to a file, but this "require" method seems like more typing than it is worth--and a lot more files (since each would have its own subroutine).

I am happy with the result as is--unless you think it would be better I use the "require" method.

Feynman 09-01-2010 04:02 PM

What do you mean by pushing sources? I have seen "push" used for arrays, but how are you suggesting it be implemented for this task?

Sergei Steshenko 09-01-2010 04:07 PM

Quote:

Originally Posted by Feynman (Post 4085304)
I was trying to use require only once. You said that was possible. I had also tried:
use strict;
use warnings;

(require 'sub.pl')->('10speed705');
('sub.pl')->('10speed705');

which did not work either. I managed to get my hash of hashes working. I have it as a package. I will change it to a file, but this "require" method seems like more typing than it is worth--and a lot more files (since each would have its own subroutine).

I am happy with the result as is--unless you think it would be better I use the "require" method.

Did you try my code as is ?

Your

Code:

('sub.pl')->('10speed705');
makes no sense - because '->' is dereferencing and "('sub.pl')" is not a reference. The code I published does make sense - I copy-pasted the screen session, you can verify yourself that the code works. In my code I do dereference a reference. I again suggest first understanding every detail of my code.

Sergei Steshenko 09-01-2010 04:08 PM

Quote:

Originally Posted by Feynman (Post 4085307)
What do you mean by pushing sources? ...

You wrote

Code:

require 'sub.pl'
, so I want to see the contents of 'sub.pl' file.

Feynman 09-01-2010 04:35 PM

Here is sub.pl:

use strict;
use warnings;

sub {
my ($person) = @_;
warn "Hello $person";
};

and yes, I tried your code as is. It worked fine. I was trying to figure out how to add another line that did not use the "require" statement.

Sergei Steshenko 09-01-2010 04:50 PM

Quote:

Originally Posted by Feynman (Post 4085344)
Here is sub.pl:

use strict;
use warnings;

sub {
my ($person) = @_;
warn "Hello $person";
};

and yes, I tried your code as is. It worked fine. I was trying to figure out how to add another line that did not use the "require" statement.

First, a cosmetic note - .pl extension is for Perl scripts; .pm extension is for Perl modules, your 'sub.pl' as well as my 'sub.prl' is neither Perl script nor Perl module, and that's why I chose a different extension.

Now back to the core issues - when require'd in 'main' what kind of thing does your 'sub.pl' and my 'sub.prl' return ? Justify your answer, i.e. describe how 'require' works.


All times are GMT -5. The time now is 02:38 AM.