Hi Larry, >>> First of all, I have generally found the Bean-style getter/setter >> approach to >>> be a sign of poor encapsulation to begin with. You shouldn't be >>> mucking >> with >>> internal elements of an object in the first place, period. More >>> details on >>> that here: >>> >>> http://www.garfieldtech.com/blog/property-visibility >> >> Interesting post, although I can't say I agree with your views. Your >> post >> leaves me wondering how the user is expected to get or give data to a >> class (for example, if I'm not supposed to do $customer->name or >> $customer-getName(), how do I get the customers name?). Additionally, >> you >> are forgetting the real power of properties, which is the ability to >> generate a get value, and process a set value, because get/set are >> methods. Properties are hardly just an indirection layer around an >> underlying piece of data. > > The idea of a ->getName() method for retrieving a person's name is fine. > My point there is that any assumption that it corresponds to a ->name > class member (as Bean definitions require) is invalid on its face. (The > context there is a lengthy ongoing debate regarding the use of public > vs. protected class members, with my basic point being that class > members are an implementation detail and if you care about them in the > first place then you have a bug. Yes, it's a deliberately stringent > position.)
Right, I think I understand the whole "Bean" thing now. Its just a struct, but has get/set methods instead of public properties? In that case, that is rather silly. A get/set method should not be required to correspond to any underlying value. A get could even return a constant, inline value for that matter. It shouldn't matter what a get returns, as long as it returns something! I do not agree with "class members are an implementation detail". I would say "private/protected members/methods are an implementation detail", which is true no matter how you slice it. There are perfectly valid reasons for exposing public class members. Heck I make classes that are just a set of public class members, and do not even have methods. This is what a "struct" is in C, C++ and C#. Its just a storage container (like a bean in java, but without silly methods for every class member). Arguably an array could be used for this, but an array has less structure and is not properly suited for a well-defined type. > What I'm seeing here is that whether properties are intended as an > indirection layer for class members (eg, a more robust __get/__set) or > not is a fuzzy question. On the one hand they are (since the goal of > the syntax is to make it irrelevant to the caller which is happening), > but on the other they're supposed to be something different that can do > all kinds of on the fly behavior. Properties can be thought of as a __get/__set that only handle a single "class member name" each. They are for single members, while __get/__set is generically for all members. I can see how you would call "__get/__set" and indirection layer because, since you are handling the values generically, doing anything other than indirection is too complicated. But when you are writing accessors for a single defined member, its easier to be more robust - you can do anything you could do in a normal method. >>> - Which also brings up an interesting question: >>> >>> class Foo { >>> public $a = 1; >>> protected $b = 2; >>> >>> public property $a { get { return 3; } } >>> public property $b { get { return 4; } } >>> } >>> >>> $f = new Foo(); >>> print $f->a . PHP_EOL; // Does this print 1 or 3? >>> print $f->b . PHP_EOL; // Does this print 2 or 4, or error? >> >> Both of those throw an error. Properties and variables share the same >> namespace, so you cannot define a property and variable with the same >> name. > > Is this consistent with methods? Do those share a namespace, too? (I > don't actually recall off the top of my head.) methods and variables have their own namespaces. This is because they are called differently: // variable $a print $f->a; // method a() print $f->a(); But variables and properties would be called the same way (both $f->a;). Because of this, they need to share the same namespace in order to avoid ambiguity. This is in fact a feature of properties, because this way an existing variable can later be replaced with a property, and all calling code will continue to work (or at least will compile). >> This is what I would imagine seeing, and would compile: >> >> class Foo { >> private $_a = 1; >> protected $_b = 2; >> >> public property $a { get { return 3; } } >> public property $b { get { return 4; } } >> } >> >> As you can see, there is no conflict or confusion this way. > > True, although for the record I have always detested the underscore > prefix on variables as a difficult to read hack. :-) To be honest, I also detest the underscore prefix. In C# we use camel case for public and pascal case for private, but because PHP is case-insensitive, that (very unfortunately) is not possible. C# example: class Foo { private int fooBar = 1; protected int fooBaz = 2; public int FooBar { get { return 3; } } public int FooBaz { get { return 4; } } } print(fooBar);// 1 print(FooBar);// 3 - Dennis -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php