in reply to OO best practice basic questions

First of all, is there a preferred style for "new" constructors? Specifically one which will be taking hash value/key pairs as attributes?

In Perl, TIMTOWTDI, There Is More Than One Way To Do It :-)

However, if your constructor has more than ~3 arguments, a hash is probably better - especially if some arguments are optional.

Secondly, is there a way to tell how many objects have been created/exist in a particular class?

Again TIMTOWTDI, a quick implementation might have a global variable in the package as a counter, which gets incremented in new and decremented in DESTROY. If there is more than one way to create an object and/or there are subclasses, one has to watch out that those are covered.

And lastly, what is the best way to access individual object attributes? Always through a method or can you access them directly?

Again, it depends. If your class is just a blessed hash, there is no practical way from stopping anyone to dig into the hash other than telling people not to in the documentation. However, from outside the class, it's normally preferred to abstract it and go through accessors, because that hides the internal storage details and allows for things like validation. From inside the class, how you access fields depends on whether the accessors do more than just get/set a value, such as validation.

Your code looks ok. I'd just recommend adding individual accessors for the fields, the change_nums and dump methods kind of break encapsulation. Also, for real code, you'd probably want to put each class in its own file; at the very least you should put the package in its own block ({ package Foo; ... }).

The Perl documentation contains more info on OO, a good starting point is probably perlootut.

Replies are listed 'Best First'.
Re^2: OO best practice basic questions
by tobyink (Canon) on Aug 27, 2014 at 20:16 UTC

    "However, from outside the class, it's normally preferred to abstract it and go through accessors"

    Even from inside the class, you should access fields/attributes via the accessors. Otherwise you'll make life harder for yourself if/when you need to subclass your class.

    "a good starting point is probably perlootut"

    w00t! I just noticed that as of Perl 5.20, this document links to one of my modules. :-)

Re^2: OO best practice basic questions
by Amblikai (Scribe) on Aug 27, 2014 at 14:39 UTC

    Thanks very much for your reply!

    Couple of questions though:

    What do you mean by individual accessors? Do you mean actually have a separate method for each field like "dump_num1"?

    And i'm not totally familiar with modules/packages. How do i put the package in a separate file? For example, if i have the package in "Numbers.pm" do i then need to go through the process of using Makefile.pl etc? Or do i need to modify @INC at all?

    Thanks again for your help!

      What do you mean by individual accessors? Do you mean actually have a separate method for each field like "dump_num1"?

      Yes, although I wouldn't name it that :-) Here's an example of a common, simple implementation:

      sub num1 { my $self = shift; $self->{num1} = shift if @_; return $self->{num1}; }

      That'll let you get the current value with $oo->num1 and set a value with $oo->num1(123);

      And i'm not totally familiar with modules/packages.

      Your file Numbers.pm would start with package Numbers; use warnings; use strict; and end with 1; (the file needs to return a true value), and then the normal way to include it would be via use Numbers; - that's it. @INC includes the current working directory ., so initially you wouldn't need to change @INC at all if all your files are in the same directory. Later on, once you get into actually building a real library, you can deal with @INC - see for example lib or the -I switch.

        Thanks! I've put my package/class in a separate file now. That's more than enough for now really.

      If you 'use <module>' in your code, perl will search in the @INC array of directories (observed with perl -V) for that <module>.pm and import it. Also, the command perldoc -q 'How do I add a directory ' should give more ways to add directories at runtime. For procedural based modules, not object oriented, there is more information worth reading in the documentation for Exporter. 'perldoc Exporter'.

      You do not need to do the Makefile to make everything work on your machine, but if you want to start sharing it, like on CPAN, you would want to use one of the mod builder tools like module-starter and write a bunch of tests to make the module complete, documented, and robust like.