Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: Re: Re: Re: Re: This is why I use Perl

by tilly (Archbishop)
on Nov 08, 2003 at 23:28 UTC ( #305611=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Re: Re: This is why I use Perl
in thread This is why I use Perl

Disagreed.

To me this is not about the ability or capability of a given language, but about the principles of encapsulation, OO programming and the best practice for OO programming. You don't do things that's doable, if they are not the best practice.

I strongly suspect that you misunderstood the point of what I was trying to say. Probably because I didn't describe it in enough detail for you to clearly visualize what I described. So here it is in detail.

In Ruby it is customary that if you want to write get/set methods for an attribute named, say, bar, you name the get method bar, and the set method bar=. The reason is that Ruby has a nice piece of syntactic sugar, foo.bar = baz is translated into foo.bar=(baz). Therefore people can use your get/set methods in a simple way. Now lets take a simple piece of working Ruby to show this in practice:

# Example simple class class Foo def initialize (aBar) @bar = aBar; end def bar @bar; end def bar= (aBar) @bar = aBar; end end # Example usage foo = Foo.new("Hello"); puts foo.bar; # prints "Hello\n" foo.bar = "World"; puts foo.bar; # prints "World\n"
And you see that you have normal get/set methods under the hood, in which we don't do much. They are, in fact, equivalent to the ones that you wrote above.

Now let me write the same class in a different way:

class Foo attr_accessor :bar; # Could add , :baz, :and, :others... def initialize (aBar) @bar = aBar; end end
This is exactly the same as what I already had, except that I did less writing and the necessary bar and bar= methods will be implemented natively and hence run a bit faster.

Therefore in Ruby if you have decided to write loads of public get/set methods, there is absolutely no reason to write them yourself. Just declare a bunch of public (yes, Ruby allows you to differentiate between public, private, and protected) ones with attr_accessor instead. If one of those accessors needs to do something more complex later (like add validation), that is easily enough changed later, transparently to existing code.

The decision about whether to have public get/set methods is an entirely tangential question.

In Perl you can do something similar, but the case for doing it is far weaker than it is in Ruby. If you have created your objects like most people do, as anonymous hashes, then you can move the implementation elsewhere and replace the anonymous hashes with anonymous tied hashes. You now get the ability in your FETCH, STORE, DELETE etc methods to hide specific fields, sanity check others, etc. All transparently to existing code.

One way that you could do it is take what I did at Class::FlyweightWrapper and modify it by having the wrapping objects be references to tied anonymous hashes (with an arbitrary tying class) rather than anonymous scalars. This is doable, but takes a fair amount of work, and as I said, is clearly a suboptimal approach. I might consider it as a retroactive fix for a bad situation, but I wouldn't plan on doing things that way.

In Java if someone has decided to allow the properties of an object be directly exposed, I don't believe that you can later replace that with get/set methods without having to visit existing code that used the old API. Therefore the possibility that you might some day, maybe, want to change your implementation and do something sophisticated in your get/set methods means that you must now hide properties and write get/set methods.

Therefore while the principles of encapsulation, OO programming, etc do not change between languages, best practices may. In particular what is best practice in Java (writing lots of simple get/set methods) is not best in Ruby because the capabilities of the language give you a better option. In Perl if you get it wrong, you theoretically can fix things afterwards, but probably don't want to because the ways of doing it are problematic.

Replies are listed 'Best First'.
Re^6: This is why I use Perl
by adrianh (Chancellor) on Nov 10, 2003 at 00:48 UTC
    The decision about whether to have public get/set methods is an entirely tangential question.

    This is sometimes called the "Uniform Access Principle" (coined, I think, by Meyer in his Object Oriented Software Construction - my copy's gone walk about so I can't check).

    As tilly points out, by keeping the attribute and method syntax identical we're free to change our implementation without having to change the API.

Re: Re: Re: Re: Re: Re: This is why I use Perl
by zby (Vicar) on Nov 10, 2003 at 11:16 UTC
    It seems to be doable by source filters. And how about Perl 6? Will it be possible in Perl 6? That retrofitting is sucha a great idea! Those getter, setter methods clutter so much the code while usually they don't add any new logic. The only reason for them is future compatibillity.
      It will almost definitely work in Perl6. IIRC object attributes were slated to be accessibly by the dot operator on the object instance, which is the same way methods are called. But we'll have to wait for A12 for a definite answer.

      Makeshifts last the longest.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://305611]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2018-08-21 23:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Asked to put a square peg in a round hole, I would:









    Results (204 votes). Check out past polls.

    Notices?