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

Hello everybody, I am currently struggling about how are we supposed to implement persistent variables in perl.

Let me clarify myself;

I have a Module which handle the users data, it contain a memberlist variable which is initially undefined.

My goal is to populate the list variable only once by reading a file.

The flow should theoretically be as follow :

My current tests shows that the variable either get unloaded after being populated from inside the package, or it always read the file to fetch the variables.

How am I supposed to implement this? I thought the code within package was only run at compile time unless it was within a sub.

I would still consider myself as a beginner when it come to server-side/perl programming, so don't hesitate to point out any flaws that would occur from using this kind of flow in a real-world case.

On a side note, if you have open source code that you strongly recommend studying available anywhere, please let me know. I used to read a lots about YABB Forum code but the more I read about it, the more I realize that the code is not strong / very efficient.

Thanks

###################################

Update

After further testing with the singleton patterns (Thanks McA) and my previous implementation, I have realized that the problem does not really reside in the semantics but in the way the perl software works

After a script has been executed, all the packages are unloaded from memory. Is there any way of making sure a package remain alive?

Replies are listed 'Best First'.
Re: Data Persistence
by McA (Priest) on Nov 20, 2014 at 14:21 UTC

    Hi,

    you're talking about server side programming which let me assume you have a kind of client server environment. That would mean you have concurrent accesses to the @MemberList, which means you have to build a system which serializes writing accesses to this list.

    When this is true, then a singleton object comes to my mind. When you instantiate the object the very first time, the file is read, afterwards every access delivers the same in memory representation. Writing accesses and persistence could be controlled by this objects methods.

    Just a rough idea.

    Regards
    McA

      This is the approach I felt like using earlier, however I thought my current understanding of how the code is handled within scripts and packages would make this pointless. Singletons always kind of feel hackish to me as well, however if you believe this would be the best approach, I will probably go with it.

      This is how I believe the language works:

      • Default Perl scripts are always instanced
      • Module assigned using the "use" statement are only run once compile time, reference is then used to call the subroutines
      • Module/Files assigned using the "require" statement are always loaded using a fresh instance
      Thanks for the suggestion :)

        I called it Singleton to have a name for something where exactly one instance exists. How you want to implement this is a matter of taste.

        IMHO you should use a packages function or a class' method to access this variable. As soon as you let it access from the outside of the package you don't have control over who changes what when. That makes concurrency hard. If you don't have concurrency than so what. But there is always also the requirement of testing which makes it feasible to encapsulate.

        Be careful: use is (besides importing) a require at compile time. But a require is also just done once for a module. Have a look at perldoc -f require.

        McA

Re: Data Persistence
by CountZero (Bishop) on Nov 21, 2014 at 07:16 UTC
    After a script has been executed, all the packages are unloaded from memory. Is there any way of making sure a package remain alive?
    Your package with the memberlist only lives by the grace of your scripts use-ing it. Once your script ends, that package ends as well.

    Perl modules do not exist by themselves, they are just blobs of code that are used by scripts and discarded when the script ends.

    What you really need is to put your memberlist in a database (such as SQLite for instance) and then your scripts call the data out of the database. A well behaved database does not have to read the whole database everytime you connect to it, so it is pretty efficient and it gets actually more efficient (compared to a flat file you have to read in everytime) the more data you have.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
      Once your script ends, that package ends as well.
      Unless you run under mod_perl or a similar environment that keeps the modules loaded.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
        mod_perl did not keep the modules loaded (if I remember correctly, it has been a long time since I used mod_perl), it kept the scripts loaded (which then persisted the use-d modules).

        You can do the same "trick" here: rewrite the script so it never ends but at the end loops back to the beginning and waits for another input.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics