Reputation: 5337
I don't know if this is the right thing to do. But I'm lookig for tutorials/articles on using objects instead of global variables to store state. For eg.
package something
# some code here...
# that generates errors and uses
# something::errors to track errors.
package something::errors
sub new {
my ($this) = @_;
bless $this;
return $this;
}
sub setErrors{
my ($this, @errors) = @_;
$this->{errors} = \@errors;
}
sub getErrors{
my ($this) = @_;
return $this->{errors};
}
Is this better than using global varibles? Any down-sides to this? Any approach which might be better?
Thanks.
Upvotes: 2
Views: 926
Reputation: 107080
You need a tutorial? Do you know that Perl has a whole mess of tutorials than you can shake a stick at?
Type in this command:
$ perldoc perl
[... a bunch of stuff]
Tutorials
perlboot Perl OO tutorial for beginners
perltoot Perl OO tutorial, part 1
perltooc Perl OO tutorial, part 2
perlbot Perl OO tricks and examples
Nifty?
All you have to do is simply to run:
$ perldoc perlboot
to see a particular tutorial. If you rather have this via a webpage checkout the on line Perl documentation.
And, they say that Perl is hard. After all, Unix comes with builtin documentation and how hard is that?
By the way, Perl objects are not all that difficult to use or understand. And, they really help clean up your code. If you're using hashes of hashes, or arrays of arrays, or arrays of hashes of hashes or arrays of hashes, you should really be using object oriented Perl.
Take a look at the latest Perl documentation on state variables. It's made to do exactly what you want.
Upvotes: 2
Reputation: 27193
I hope this answer is useful for you, even though it's a pretty abstract comment and not very focussed on the particular details of your question.
IMO, objects are most useful because they provide a way to encapsulate a chunk of data and bind it to a set of behaviors.
Several clues are observable in code that indicate OOP may be a good way to go:
So, do all (or most of) your subs have 3 or 4 common arguments?
sub whiz {
my ($foo, $bar, $baz, $pogo) = @_;
# blah
}
sub bang {
my ($foo, $bar, $baz, $whibble) = @_;
# blah
}
sub fiz {
my ($foo, $bar, $baz, $smot) = @_;
# blah
}
If you find your code looks like that, then maybe $foo
, $bar
and $baz
need to be part of an object that groups all that messy stuff in one place.
Perhaps you have a big data or state object that looks something like this:
{ Foo => [ { a => 1, z => 3 }, [qw( milk milk lemonade)], ],
quack => { round => 'the', corner => [qw( fudge is made )] },
...
}
Consider breaking this structure into smaller related, namable units. These are your objects.
Look at this structure:
{ teacher => $miss_jones,
students => [ $bobby, $suzy, $joseph, $jenny ],
principal => $mr_goodcop,
vice_principal => $mr_badcop,
custodian => $mr_mopitup,
}
And imagine that each variable was expanded into its own has with it's own set of fields. Some present in all variables, others unique to some subset of entries. But if $miss_jones is in class $teacher, we can call $miss_jones->add_student( $bobby )
, without having to worry about how Teacher stores students.
These are the principles that I use to determine when to use OOP.
Upvotes: 2
Reputation: 39158
Any approach which might be better?
See chapter 13 of Perl Best Practices why and how to use proper exceptions. This topic also has come up on Stack Overflow repeatedly: Google search, SO search, SO tags
Upvotes: 1
Reputation: 51246
Well, your package still requires a (presumably global) variable of some kind to bless and to use as argument #1 in future method calls, so I don't see how this improves things in that respect. IOW you need a global variable regardless of whether you store the errors in a plain global array or use a something::errors
object to hold them.
While using the object doesn't affect whether you need to keep global state, it does mean that you can control what operations can be performed more finely, and that is good for maintenance. (Maintenance is all about restricting the possible set of behaviours of any given piece of code to a manageable size.)
I think the important question is: "Will this list of errors ever be sufficiently different from a plain array to justify using a special type for it?" If the only operations you have are setErrors()
and getErrors()
, and you do not anticipate ever doing any filtering/processing during a setErrors()
call, then I would say "no", since these operations are together powerful enough to let you do anything you could do with a plain array, so they don't provide any "safety". If on the other hand you wanted to avoid the possibility that errors are accidentally removed from the list, you could expose an addErrors()
method instead of a setErrors()
method, and you could now more convincingly argue that there was some benefit to using a separate type.
Upvotes: 1