Hi,
Here is an RFC proposal about a syntax extension for PHP. The purpose is to
manage precisely the visbiliy of attributes, by separating reading and
writing access.
First of all, I know there is already an RFC about attributes ("Property
get/set syntax" [1]). Its goal is mainly different, but I'll discuss it
lower.
THE PROBLEM
In my experience, one of the major usage of getters is when you want to
have an attribute, readable (but not writable) from outside the object.
More, the attribute's visibilty is then chosen between private and
protected, depending on your inheritance design.
The result is not really satisfying:
- You have to write getter's code. Maybe, it's just a simple return, but
every line of code should be useful, not a workaround. - You ended with 2 syntaxes; $obj->attr when the attribute is public, but
$obj->getAttr() when you must use a getter. It's a bit schizophrenic.
THE IDEA
I suggest to be able to separate reading visibility and writing visibility,
using a colon to separate them. If only one visibility is given, it will be
used for both reading and writing access.
For example:
class A {
public $a; // public reading, public writing
public:public $b; // the same
public:protected $c; // public reading, protected writing
public:private $d; // public reading, private writing
public:const $e; // public reading, no writing allowed
protected $f; // protected reading, protected writing
protected:protected $g; // the same
protected:private $h; // protected reading, private writing
protected:const $i; // protected reading, no writing allowed
private $j; // private reading, private writing
private:private $k; // the same
private:const $l; // private reading, no writing allowed
}
As you can see, I think that writing access should be more restrictive than
reading access (or equivalent to it). A "private:public" visibility would
make no sense.
SOURCE CODE
I did a patch. It kinda works, but I'm still working on it (because I'm
still learning Zend Engine's internals).
The code on GitHub: https://github.com/Amaury/php-src
All advises are welcome.
PRIOR WORK
As I said before, the "Property get/set syntax" RFC is in discussion. My
proposal doesn't focus on the same goals, but they could be fully
compatible.
Thus, we would be able to write this kind of code:
class A {
// $str has public reading and private writing,
// and manage french quotes
public:private $str {
get { return "«" . $this->str . "»"; }
set { $this->str = trim($value, "«»"); }
}
}
Maybe you saw that the "Property get/set syntax" RFC has an intended syntax
for read-only and write-only attributes. From my point of view, there is a
deep and clean separation between a getter/setter syntax and an extended
visibility syntax. It shouldn't be in the same RFC.
More, the proposed "read-only" and "write-only" keywords are less precise
and powerful than what I'm suggesting.
I would be happy to discuss all that with you guys.
Best regards,
Amaury Bouchard
[1] : https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented
This seems pretty useful, but could technically be accomplished using the
get/set syntax already proposed. Obviously this is a cleaner implementation
however.
Hi,
Here is an RFC proposal about a syntax extension for PHP. The purpose is to
manage precisely the visbiliy of attributes, by separating reading and
writing access.First of all, I know there is already an RFC about attributes ("Property
get/set syntax" [1]). Its goal is mainly different, but I'll discuss it
lower.THE PROBLEM
In my experience, one of the major usage of getters is when you want to
have an attribute, readable (but not writable) from outside the object.
More, the attribute's visibilty is then chosen between private and
protected, depending on your inheritance design.The result is not really satisfying:
- You have to write getter's code. Maybe, it's just a simple return, but
every line of code should be useful, not a workaround.- You ended with 2 syntaxes; $obj->attr when the attribute is public, but
$obj->getAttr() when you must use a getter. It's a bit schizophrenic.THE IDEA
I suggest to be able to separate reading visibility and writing visibility,
using a colon to separate them. If only one visibility is given, it will be
used for both reading and writing access.For example:
class A {
public $a; // public reading, public writing
public:public $b; // the same
public:protected $c; // public reading, protected writing
public:private $d; // public reading, private writing
public:const $e; // public reading, no writing allowedprotected $f; // protected reading, protected writing protected:protected $g; // the same protected:private $h; // protected reading, private writing protected:const $i; // protected reading, no writing allowed private $j; // private reading, private writing private:private $k; // the same private:const $l; // private reading, no writing allowed
}
As you can see, I think that writing access should be more restrictive than
reading access (or equivalent to it). A "private:public" visibility would
make no sense.SOURCE CODE
I did a patch. It kinda works, but I'm still working on it (because I'm
still learning Zend Engine's internals).
The code on GitHub: https://github.com/Amaury/php-src
All advises are welcome.PRIOR WORK
As I said before, the "Property get/set syntax" RFC is in discussion. My
proposal doesn't focus on the same goals, but they could be fully
compatible.Thus, we would be able to write this kind of code:
class A {
// $str has public reading and private writing,
// and manage french quotes
public:private $str {
get { return "«" . $this->str . "»"; }
set { $this->str = trim($value, "«»"); }
}
}Maybe you saw that the "Property get/set syntax" RFC has an intended syntax
for read-only and write-only attributes. From my point of view, there is a
deep and clean separation between a getter/setter syntax and an extended
visibility syntax. It shouldn't be in the same RFC.
More, the proposed "read-only" and "write-only" keywords are less precise
and powerful than what I'm suggesting.I would be happy to discuss all that with you guys.
Best regards,
Amaury Bouchard
[1] : https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented
--
Brandon Wamboldt
Programmer / Web Developer
StackOverflow Careers
Profilehttp://careers.stackoverflow.com/brandonwamboldt- GitHub
Profile https://github.com/brandonwamboldt -
LinkedInhttps://github.com/brandonwamboldt -
My Blog <http://brandonwamboldt.ca/
2012/7/15 Brandon Wamboldt brandon.wamboldt@gmail.com
This seems pretty useful, but could technically be accomplished using the
get/set syntax already proposed. Obviously this is a cleaner implementation
however.
As I said, the get/set syntax RFC propose a "read-only" and a "write-only"
keywords.
For example, it will not allow you to have an attribute readable only by
descendant classes (and by the current class, of course), and at the same
time only writable by the current class.
PHP is an object-oriented language with public/protected private
visibility. Visibility conveys meanings, and we shouldn't loose these
meanings when we add new functionalities.
Once again, the purpose of the get/set syntax RFC is to define getters and
setters directly where attributes are defined. Attributes' visibility is a
distinct question, which deserve a distinct answer (even if there is some
obvious connections).
Hi,
Here is an RFC proposal about a syntax extension for PHP. The purpose is
to
manage precisely the visbiliy of attributes, by separating reading and
writing access.First of all, I know there is already an RFC about attributes ("Property
get/set syntax" [1]). Its goal is mainly different, but I'll discuss it
lower.THE PROBLEM
In my experience, one of the major usage of getters is when you want to
have an attribute, readable (but not writable) from outside the object.
More, the attribute's visibilty is then chosen between private and
protected, depending on your inheritance design.The result is not really satisfying:
- You have to write getter's code. Maybe, it's just a simple return, but
every line of code should be useful, not a workaround.- You ended with 2 syntaxes; $obj->attr when the attribute is public, but
$obj->getAttr() when you must use a getter. It's a bit schizophrenic.THE IDEA
I suggest to be able to separate reading visibility and writing
visibility,
using a colon to separate them. If only one visibility is given, it will
be
used for both reading and writing access.For example:
class A {
public $a; // public reading, public writing
public:public $b; // the same
public:protected $c; // public reading, protected writing
public:private $d; // public reading, private writing
public:const $e; // public reading, no writing allowedprotected $f; // protected reading, protected writing protected:protected $g; // the same protected:private $h; // protected reading, private writing protected:const $i; // protected reading, no writing allowed private $j; // private reading, private writing private:private $k; // the same private:const $l; // private reading, no writing allowed
}
As you can see, I think that writing access should be more restrictive
than
reading access (or equivalent to it). A "private:public" visibility would
make no sense.SOURCE CODE
I did a patch. It kinda works, but I'm still working on it (because I'm
still learning Zend Engine's internals).
The code on GitHub: https://github.com/Amaury/php-src
All advises are welcome.PRIOR WORK
As I said before, the "Property get/set syntax" RFC is in discussion. My
proposal doesn't focus on the same goals, but they could be fully
compatible.Thus, we would be able to write this kind of code:
class A {
// $str has public reading and private writing,
// and manage french quotes
public:private $str {
get { return "«" . $this->str . "»"; }
set { $this->str = trim($value, "«»"); }
}
}Maybe you saw that the "Property get/set syntax" RFC has an intended
syntax
for read-only and write-only attributes. From my point of view, there is a
deep and clean separation between a getter/setter syntax and an extended
visibility syntax. It shouldn't be in the same RFC.
More, the proposed "read-only" and "write-only" keywords are less precise
and powerful than what I'm suggesting.I would be happy to discuss all that with you guys.
Best regards,
Amaury Bouchard
[1] : https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented
--
Brandon Wamboldt
Programmer / Web DeveloperStackOverflow Careers Profilehttp://careers.stackoverflow.com/brandonwamboldt- GitHub
Profile https://github.com/brandonwamboldt - LinkedInhttps://github.com/brandonwamboldt -
My Blog <http://brandonwamboldt.ca/
Hi,
Here is an RFC proposal about a syntax extension for PHP. The purpose is to
manage precisely the visbiliy of attributes, by separating reading and
writing access.First of all, I know there is already an RFC about attributes ("Property
get/set syntax" [1]). Its goal is mainly different, but I'll discuss it
lower.
I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the most
common cases. If you do need visibility control, it is possible too:
public $property {
get { ... }
protected set { ... }
}
So what does this proposal add to it?
Nikita
An ugly, confusion-causing syntax.
Hi,
Here is an RFC proposal about a syntax extension for PHP. The purpose is to
manage precisely the visbiliy of attributes, by separating reading and
writing access.First of all, I know there is already an RFC about attributes ("Property
get/set syntax" [1]). Its goal is mainly different, but I'll discuss it
lower.I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the most
common cases. If you do need visibility control, it is possible too:public $property {
get { ... }
protected set { ... }
}So what does this proposal add to it?
Nikita
--
--
Andrew Faulds (AJF)
http://ajf.me/
You already have the read-only/write-only option proposed on that RFC
- by not defining set and vice-versa for write only - or by inserting
new keywords (not sure if this is needed/optimal).
And nowhere in PHP do we have the syntax you propose as A:B, and I
even recall a short array [a:1, b:2] syntax from being promptly
rejected in the past, although I can't recall the argument against it.
Plus that RFC can allow for additional implementation of something
like a lambda/other function calls; a lot of things way more
useful/interesting to see than just controlling visibility.
An ugly, confusion-causing syntax.
I'm sorry, but how does this add anything to the discussion?
Qualify your statement, please. What do you find "ugly" about the
syntax, and why? Where do you see confusion arising from the syntax -
what problems do you foresee arising?
Making judgmental statements without any context like the one you made
above does nobody any good, and if you can't find the time to qualify
them properly, it'd be better for everybody if you simply didn't post.
</end rant>
Hi,
Here is an RFC proposal about a syntax extension for PHP. The purpose is to
manage precisely the visbiliy of attributes, by separating reading and
writing access.First of all, I know there is already an RFC about attributes ("Property
get/set syntax" [1]). Its goal is mainly different, but I'll discuss it
lower.I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the most
common cases. If you do need visibility control, it is possible too:public $property {
get { ... }
protected set { ... }
}So what does this proposal add to it?
Nikita
--
--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
2012/7/16 Nikita Popov nikita.ppv@gmail.com
I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the most
common cases. If you do need visibility control, it is possible too:public $property {
get { ... }
protected set { ... }
}So what does this proposal add to it?
Yes, but only if you have to write an accessor.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
With my syntax:
public:private $a; (read it aloud "public reading, private writing")
With the existing RFC:
public $a {
private set { $this->a = $value; }
}
Which one is better? Why should I write code for that?
If you read the existing RFC, you'll see that all examples involve a
specific case: when you have a "fake" attribute, which manipulates date
stored in other attributes. The given example is an $Hours attributes,
which is calculated from the private $Seconds attribute.
Again, it could be very useful. But it doesn't work all the time.
How much syntactic sugar do we really need? Why add two ways to do something?
2012/7/16 Nikita Popov nikita.ppv@gmail.com
I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the most
common cases. If you do need visibility control, it is possible too:public $property {
get { ... }
protected set { ... }
}So what does this proposal add to it?
Yes, but only if you have to write an accessor.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
With my syntax:
public:private $a; (read it aloud "public reading, private writing")With the existing RFC:
public $a {
private set { $this->a = $value; }
}Which one is better? Why should I write code for that?
If you read the existing RFC, you'll see that all examples involve a
specific case: when you have a "fake" attribute, which manipulates date
stored in other attributes. The given example is an $Hours attributes,
which is calculated from the private $Seconds attribute.
Again, it could be very useful. But it doesn't work all the time.
--
Andrew Faulds (AJF)
http://ajf.me/
My point is not to add two ways to do the same thing.
What I'm humbly suggesting to do is to keep the core idea of the existing
RFC (make things easier when you have to write getters/setters), and think
about another syntax for managing reading and writing visibilities.
2012/7/16 Andrew Faulds ajfweb@googlemail.com
How much syntactic sugar do we really need? Why add two ways to do
something?2012/7/16 Nikita Popov nikita.ppv@gmail.com
I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the most
common cases. If you do need visibility control, it is possible too:public $property {
get { ... }
protected set { ... }
}So what does this proposal add to it?
Yes, but only if you have to write an accessor.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
With my syntax:
public:private $a; (read it aloud "public reading, private writing")With the existing RFC:
public $a {
private set { $this->a = $value; }
}Which one is better? Why should I write code for that?
If you read the existing RFC, you'll see that all examples involve a
specific case: when you have a "fake" attribute, which manipulates date
stored in other attributes. The given example is an $Hours attributes,
which is calculated from the private $Seconds attribute.
Again, it could be very useful. But it doesn't work all the time.--
Andrew Faulds (AJF)
http://ajf.me/
My point is not to add two ways to do the same thing.
What I'm humbly suggesting to do is to keep the core idea of the existing
RFC (make things easier when you have to write getters/setters), and think
about another syntax for managing reading and writing visibilities.
The thing is that coming down to two options of a new A:B syntax or
the RFC proposal, the RFC fits on the current syntax and allows for
more flexibility such as expanding with other function calls, I think
that would get the support+votes behind it.
The only thing I'm not yet particulartly fond of in this RFC is the
$value variable, but I guess there might not be another way around it,
unless we go for a more complex syntax.
--f46d0446312cc5e06104c4f42161
Content-Type: text/plain; charset=ISO-8859-1My point is not to add two ways to do the same thing.
What I'm humbly suggesting to do is to keep the core idea of the
existing RFC (make things easier when you have to write
getters/setters), and think about another syntax for managing reading
and writing visibilities.
My first impression, being familiar with the other proposal, was that
this looked like duplication. However, on looking at the examples, I
have to admit that I really like the approach -- in many cases, it
obviates the need for a getter entirely. It would help dry up a lot of
code, reduce the number of method calls overall, and still enforce
internal logic when setting the value in the first place.
I like it; it feels elegant.
2012/7/16 Andrew Faulds ajfweb@googlemail.com
How much syntactic sugar do we really need? Why add two ways to do
something?2012/7/16 Nikita Popov nikita.ppv@gmail.com
I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the most
common cases. If you do need visibility control, it is possible too:public $property {
get { ... }
protected set { ... }
}So what does this proposal add to it?
Yes, but only if you have to write an accessor.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
With my syntax:
public:private $a; (read it aloud "public reading, private writing")With the existing RFC:
public $a {
private set { $this->a = $value; }
}Which one is better? Why should I write code for that?
If you read the existing RFC, you'll see that all examples involve a
specific case: when you have a "fake" attribute, which manipulates date
stored in other attributes. The given example is an $Hours attributes,
which is calculated from the private $Seconds attribute.
Again, it could be very useful. But it doesn't work all the time.--
Andrew Faulds (AJF)
http://ajf.me/--f46d0446312cc5e06104c4f42161--
--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Thank you Matthew. I had the feeling that my proposal was dismissed a bit
quickly by some people, while I think it's how object-oriented languages
should handle attributes' visibility.
I still think it's very simple and elegant, and more coherent in some
situations (those situations targeted by the proposal).
I would like everybody give 5 minutes to this idea [1] :-)
[1] : http://37signals.com/svn/posts/3124-give-it-five-minutes
2012/7/21 Matthew Weier O'Phinney weierophinney@php.net
--f46d0446312cc5e06104c4f42161
Content-Type: text/plain; charset=ISO-8859-1My point is not to add two ways to do the same thing.
What I'm humbly suggesting to do is to keep the core idea of the
existing RFC (make things easier when you have to write
getters/setters), and think about another syntax for managing reading
and writing visibilities.My first impression, being familiar with the other proposal, was that
this looked like duplication. However, on looking at the examples, I
have to admit that I really like the approach -- in many cases, it
obviates the need for a getter entirely. It would help dry up a lot of
code, reduce the number of method calls overall, and still enforce
internal logic when setting the value in the first place.I like it; it feels elegant.
2012/7/16 Andrew Faulds ajfweb@googlemail.com
How much syntactic sugar do we really need? Why add two ways to do
something?2012/7/16 Nikita Popov nikita.ppv@gmail.com
I'm not sure I really understand what this adds over the existing
getter/setter proposal. read-only and write-only should cover the
most
common cases. If you do need visibility control, it is possible too:public $property {
get { ... }
protected set { ... }
}So what does this proposal add to it?
Yes, but only if you have to write an accessor.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
With my syntax:
public:private $a; (read it aloud "public reading, private
writing")With the existing RFC:
public $a {
private set { $this->a = $value; }
}Which one is better? Why should I write code for that?
If you read the existing RFC, you'll see that all examples involve a
specific case: when you have a "fake" attribute, which manipulates
date
stored in other attributes. The given example is an $Hours attributes,
which is calculated from the private $Seconds attribute.
Again, it could be very useful. But it doesn't work all the time.--
Andrew Faulds (AJF)
http://ajf.me/--f46d0446312cc5e06104c4f42161--
--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Yes, but only if you have to write an accessor.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
With my syntax:
public:private $a; (read it aloud "public reading, private writing")With the existing RFC:
public $a {
private set { $this->a = $value; }
}Which one is better? Why should I write code for that?
If you read the existing RFC, you'll see that all examples involve a
specific case: when you have a "fake" attribute, which manipulates date
stored in other attributes. The given example is an $Hours attributes, which
is calculated from the private $Seconds attribute.
Again, it could be very useful. But it doesn't work all the time.
You can also just write public $a { get; private set; }. I see that
the syntax is a bit more verbose, but I definitely prefer it to the
obscure public:private notation. With the getters/setters the meaning
is somewhat clear (public get, private set), with the colon notation
it isn't really clear.
Nikita
Are you sure that this mix of distributed visibilities (sometimes before
the attribute, sometimes before a "get" or "set" keyword) and new keywords
("read-only" and "write-only", between the initial visibility and the
attribute itself; but what is an "initial visibility" exactly?) is really
more clear?
Take this code, for instance:
public read-only $a {
protected get;
private set;
}
Yeah, I know, the "public" should be "protected". But in some years, when
you'll have some legacy code, I'm pretty sure we will see this kind of
code. It should work, the "public" visibility is just overloaded by the
"protected" and "private" visibilities. Anyway, it's perturbing.
Oh, and there is a "read-only" keyword. Damned, I added a private setter, I
forgot it was read-only and I forgot to remove it...
So, I guess it should be like that:
protected $a {
private set;
}
Then, try to read this code aloud. I'm really not sure it's better than a
simple "protected:private $a;", which could be read like "protected
reading, private writing".
2012/7/16 Nikita Popov nikita.ppv@gmail.com
On Mon, Jul 16, 2012 at 5:24 PM, Amaury Bouchard amaury@amaury.net
wrote:Yes, but only if you have to write an accessor.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
With my syntax:
public:private $a; (read it aloud "public reading, private writing")With the existing RFC:
public $a {
private set { $this->a = $value; }
}Which one is better? Why should I write code for that?
If you read the existing RFC, you'll see that all examples involve a
specific case: when you have a "fake" attribute, which manipulates date
stored in other attributes. The given example is an $Hours attributes,
which
is calculated from the private $Seconds attribute.
Again, it could be very useful. But it doesn't work all the time.You can also just write public $a { get; private set; }. I see that
the syntax is a bit more verbose, but I definitely prefer it to the
obscure public:private notation. With the getters/setters the meaning
is somewhat clear (public get, private set), with the colon notation
it isn't really clear.Nikita
That is already accounted for, both the visibility (what's inside
limits what's before the variable) as well as changing the
write-only/read-only options. If you read the RFC, when extending a
class and adding "set" method to a member that was read-only, you
overload the read-only setting...
Hence on the example you gave I expect the set method to be available
privately, and the visibility to be decreased from public to
protected.
Might not make a lot of sense to have it all together (even on legacy
code - you do review before committing, right? :), but it's accounted
for when extending classes.
If you just want an attribute that is:
- readable from everywhere
- writable from the current class only
I believe the RFC sugests:
public $a {
private set;
}
Would be enough, if I understand correctly...