in reply to Idea on a Base class API

I'm certainly not a Perl elder, but I've done a lot of OO. No offense meant, but I'd say that what you're doing is not particularly OO. If the external interfaces of your classes include exposure of all your internal data, you've defeated encapsulation. You shouldn't expose your internal data to external clients, generally.

You're defining things that are primarily data holders (like C structs). Your ideas look like they'd be good for making data holders, if that's what's important to you. This is occasionally useful, but for most people OO is about behavior: your program works because there are a bunch of objects collaborating to do the work. The responsibility for various actions is partitioned between the objects.

So what is the behavior of an object that just holds data? When we're describing its responsibility, we use terms like "holds", "remembers", "knows", etc. These terms are an indication that we've got something that is more an attribute -- a (possibly composite) data item -- than a real object with its own behavior.

One important question to answer is: what happens to my interface when I change my implementation?. If your public interface is all behavioral, it doesn't matter how (or if) you encode your object's state (data). But if you expose every field, you've tied your interface to your implementation. This causes brittleness.

Perhaps part of the problem with this kind of thinking is all the "OO" tutorials that use the same tired "Employee" and "Manager" or "BankAccount" and "Customer" examples. These are more a case of warmed-over database records than objects with real behavior, generally speaking. But then many of the people who wrote those spent too long thinking about databases.

Anyway, thanks for suggesting this; you should probably look at Class::Struct, which does much the same thing.

Replies are listed 'Best First'.
Re: Re: Idea on a Base class API
by dragonchild (Archbishop) on Jun 13, 2001 at 02:16 UTC
    I do apologize for not explaining myself more clearly. I've focused on data typing, primarily because those are the types of objects I've been working with recently. However, the goal is this:
    I have Foo and Bar and Bar inherits from Foo. Since Foo inherits from BaseClass, then all the standard C++/Java OO stuff happens. For instance, if I have the following:
    package Foo; use BaseClass; @ISA=qw(BaseClass); Foo->define_attributes( attrib1 => 'NUM', ); package Bar; use Foo; @ISA=qw(Foo); Bar->define_attributes( attrib2 => 'NUM', );

    Bar would now have two attributes - attrib2 and attrib1. This would be a full implementation of the is-a style hierarchy, something lacking in the native Perl language.

    I'm not looking to create a struct ... I know that's out there and probably done much better than I ever could. However, what I am looking to create is something that would give a solid OO foundation to someone who wants to use it, but doesn't want to re-invent the wheel.

    I don't know ... something that maybe does private, friends, shared, public, etc. I'm not quite sure on how far to take this, or even if this would be well-received by the Perl community. This would be my first modules, so I wanted to start a discussion on PM first, to see what people thought of both the idea in general and my idea in specific.

      I see... Don't worry about how it'd be received. The Perl community is very diverse. Chances are very good that if it's useful for you in the kinds of programming you're doing, it'll be useful to someone else too. If you're looking for encouragement, here's some: go for it!. Either what you build will be better than what's out there, or it'll feel better to you to use, or at least you'll learn a lot doing it. And, with CPAN and Perlmonks, you'll have the advantage of sharing it with others who might find it useful too.

      As far as the technical end, it might be useful to provide a switch of some sort to turn on/off access checking of various kinds. That is, when you're testing or developing, you can check for adherence to the contract (private/public/protected, compatible types, etc.), and be able to switch off the checking later. If you do it right, you can make it run faster without checking.

      To check for violation of visibility, you could use caller() to see where you're being called from.

      Good luck!