Bean style accessor (which is a getter): getName()
Non-bean style accessor: name()
A property in the template has to choose whether to refer to getName() or 
name().
I did use a confusing case of this where I noticed people's tendency to use 
isXyz for a boolean field name, rather than xyz.


With version 2.3.32, records were treated like other classes, so as well as 
calling methods directly,
you could use the property syntax in the template which would recognise methods 
which followed the bean accessor naming convention.

When opting-in to the new version 2.3.33 features, for records using property 
syntax in the template,
both methods following the bean accessor convention, as well as methods 
following the non-bean accessor convention are considered.
When the class is first accessed, a mapping is created between methods and 
property names.
For the examples I gave, the assumption is that beans would take precedence and 
the property "active" would map to the "isActive" method in both cases.
As there seems to be an error, either I've not understood something or there's 
a quality of implementation issue that needs to be resolved.
It's only a backwards compatibility error if we release it in its current state.


The current enum added in 2.3.33 (which I suggested renaming) is only to 
determine whether non-bean style accessors should be considered at all.
The assumption is that bean accessors would work as they always have.

ZeroArgumentNonVoidMethodPolicy.METHOD_ONLY - the 2.3.32 status quo (the 
non-bean accessors would not be considered as properties)
ZeroArgumentNonVoidMethodPolicy.BOTH_PROPERTY_AND_METHOD - the 2.3.33 value for 
records when opting in to incompatible improvements (non-bean accessors are 
also considered as properties)
ZeroArgumentNonVoidMethodPolicy.PROPERTY_ONLY - non-bean accessors are 
considered as properties, but are no longer callable directly as methods

So... what if I used the PROPERTY_ONLY value and then used my evil example:
record Evil(boolean active, boolean isActive) {}
Would the "active" property map to isActive() and active isn't useable at all 
(assuming bean accessor methods beat non-bean)?
(I guess that currently it would fail similarly to the other 2 examples),


There are lots of things we could call "policy" here (different ways of looking 
at the problem).
In this preview version we have a single enum used for two settings (one for 
records, one for normal classes).
I think we're still working out the consequences of these and whether they're a 
good idea.
We did want mixed in order to be as backwards compatible as possible for people 
already using records.
Another driving force is the desire to offer a solution that can also allow 
classes to use non-bean accessors as properties.
Possibly that approach has led to the headaches we're finding here, but all 
options may have their own trade-offs.


Simon




On Monday, 1 April 2024 at 18:07:48 BST, Denis Bredelet 
<brede...@mac.com.invalid> wrote: 





Hello,

I am talking as an outsider since I never touched the accessors configuration.

Would it make sense to have three policies?

BeanAccessorsPolicy
GetterStyleAccessorsPolicy
DefaultAccessorsPolicy (= mixed, as Simon highlighted conflicts are already 
errors so it is backward-compatible.)

— Denis.

> Le 1 avr. 2024 à 17:49, Simon Hartley <scrhart...@yahoo.co.uk.INVALID> a 
> écrit :
> 
> In terms of language, for a record's read methods, Java calls them accessors.
> For beans, I'm used to the term getter, but when expanding to also describe 
> how boolean return methods are handled,
> the term accessor is again used. It seems that zero-argument non-void is 
> trying to be distinct from the term accessor,
> because that's what we believe is necessary for backwards compatibility and 
> compatibility with beans
> (and a project could have a mixture of bean and non-bean style classes).
> 
> But trying to move the problem slightly, what do you think of the following 
> idea?
> NonBeanAccessorsPolicy.XXX (as opposed to ZeroArgumentNonVoidMethodPolicy.XXX)
> Note: I've used a plural here to try to highlight we're saying the methods 
> are non-bean, rather than the classes.
> So how does this help us when there's a conflict?
> We've implied that logic for bean accessors may be being applied as well; 
> this can be supplemented with documentation.
> Also not every future option should hang off ZeroArgumentNonVoidMethodPolicy,
> since our original intent was to describe non-bean related behavior.
> 
> 
> For 2.3.32:
> * non-bean class accessors could only be methods
> * bean class accessors could be methods and properties
> * non-bean record accessors could only be methods
> * bean record accessors are generally a mistake
> 
> For 2.3.33:
> * non-bean class accessors were added to address use cases for both records 
> and classes.
> * we haven't introduced an option to turn-off bean accessors for records to 
> solve the problem for records
> * for some projects, an option to turn-off bean accessors for classes may be 
> useful,
>  but some projects would want a mixture
> * where there is a mixture here are some approaches:
>  - prefer exposing bean properties (more likely to be backwards compatible?)
>  - prefer exposing non-bean properties (would work better with records?)
>  - error (force the user to resolve ambiguity by either using a method 
>invocation or changing their Java code)
>  - expose both (collisions?)
> 
>  
> Property collisions
> ---------------
> 
> What happens when a record has fields/components of both active and isActive?
> record Evil(boolean active, boolean isActive) {}
> 
> With the current implementation, both of the following cause an error when 
> the "active" property is used!
> record MyRecord(boolean isActive) {
>    public boolean active() {
>        return false;
>    }
>    // implicit method isActive()
> }
> record MyRecord(boolean active) {
>    public boolean isActive() {
>        return false;
>    }
>    // implicit method active()
> }
> 
> So collisions are already there, not a potential risk.
> 
> Simon
> 
> 
> 
> 
> 
> On Monday, 1 April 2024 at 12:35:44 BST, Daniel Dekany 
> <daniel.dek...@gmail.com> wrote: 
> 
> 
> 
> 
> 
> I think we need the current behavior for the
> almost-backward-compatible behavior that incompatibleImprovements
> 2.3.33 promises. (Although it's "incompatible", there's a promise that
> as far as it's 2.3.x, it only enables changes that are most likely
> won't break your application, hence when someone discovers that they
> need some of the improvements it brings, they can usually crank it up,
> and get all the other improvements too, instead of people having some
> unique permutation of "improvements" enabled.) So maybe
> ZeroArgumentNonVoidMethodPolicy.PROPERTY_ONLY should be called
> PROPERTY_UNLESS_BEAN_PROP_READ_METHOD (oh my...), and
> BOTH_PROPERTY_AND_METHOD should called
> PROPERTY_UNLESS_BEAN_PROP_READ_METHOD_AND_METHOD (even funnier name).
> And then later we can introduce other policies if needed, which are
> less backward compatible, but might be seen cleaner or more obvious.
> 
> On Sun, Mar 31, 2024 at 4:49 PM Simon Hartley
> <scrhart...@yahoo.co.uk.invalid> wrote:
>> 
>> If I was trying to do something here's an idea or two
>> (please don't feel any pressure to implement this, I'm just thinking out 
>> loud):
>> 
>> How properties are implemented is from two sources: beans and simple 
>> non-voids.
>> When the logic of both is being applied, then it's not a surprise that there 
>> are some strange interactions.
>> If I could enable them separately, then I could turn off bean properties on 
>> records and have it work as I hoped.
>> 
>> Otherwise perhaps I would need to have a backwards compatibility mode which 
>> is only enabled when using the default values.
>> Or perhaps a setting which said whether beans or simple non-voids take 
>> precedence.
>> 
>> I'm more than happy with the status quo; a few rough edges aren't the end of 
>> the world.
>> I very much appreciate the effort you've already put in and what's been done 
>> is a huge improvement.
>> 
>> Thank you so much,
>> Simon
>> 
>> 
>> 
>> 
>> On Sunday, 31 March 2024 at 02:05:32 BST, Daniel Dekany 
>> <daniel.dek...@gmail.com> wrote:
>> 
>> 
>> 
>> 
>> 
>> Yeah, it is confusing/complicated if somebody digs into it. So you
>> have `boolean isAccessible()` in a record. Because it's in a record,
>> it's a good question what the intent of the author was (plus, now that
>> the Java language makers make a mess, people will start using the same
>> pattern in all kind of classes, randomly mixed with old-style
>> getters). Like maybe it looks as a Java Beans property read method
>> only accidentally, and they want this property-like thing to be called
>> "isAccessible". But I think the most likely, by far, is that the
>> authors are just confused about what the convention now is. Also,
>> Java's java.beans.Introspector tells us that that's what it is: a Java
>> Beans property called "accessible". FreeMarker doesn't try to guess if
>> from the name. Also, this happens to be the most backward compatible
>> behavior too.
>> 
>> The end result is as below.
>> 
>> These will work:
>> myRecord.accessible - boolean value, because it's a Java Beans
>> property called "accessible"
>> myRecord.isAccessible() - which returns boolean, because a such a
>> public method exists in Java, and therefore people expect it to work
>> like in Java.
>> 
>> This doesn't work:
>> myRecord.accessible() - because there's no such method in Java, so it
>> would be quite absurd
>> myRecord.isAccessible - is not a boolean value, but a method, because
>> that's how it always was with JavaBean property read methods.
>> 
>> And then, you say, maybe myRecord.isAccessible should also be a
>> boolean? I don't know... It's more backward incompatibility risk for
>> sure.
>> 
>> Also, note that if something is related to JavaBean properties, the
>> ZeroArgumentNonVoidMethodPolicy doesn't apply. We decided that it's a
>> JavaBean property read method, and end of story.
>> 
>> That the ZeroArgumentNonVoidMethodPolicy name doesn't convey the exact
>> meaning is true. Not sure what a better name could be though, that's
>> not comically long.
>> 
>> On Sat, Mar 30, 2024 at 1:11 AM Simon Hartley
>> <scrhart...@yahoo.co.uk.invalid> wrote:
>>> 
>>> Similarly, for a record with a field (component) called isActive,
>>> its property name is currently "active" and not "isActive".
>>> Additionally, this exposed property is callable as a method even when the 
>>> setting is PROPERTY_ONLY,
>>> due to it being considered a bean property and not a record property.
>>> 
>>> Is this the compromise we're making and something we'll live with,
>>> or should we add more complexity so that this doesn't always apply?
>>> 
>>> 
>>> 
>>> On Friday, 29 March 2024 at 23:29:31 GMT, Simon Hartley 
>>> <scrhart...@yahoo.co.uk.invalid> wrote:
>>> 
>>> 
>>> 
>>> I've worked out what my confusion was:
>>> 
>>> I was setting it to METHOD_ONLY and then becoming confused that the bean 
>>> get method still worked as a property.
>>> Of course, this setting only affects zero-argument non-void methods which 
>>> ALSO aren't bean getter methods.
>>> 
>>> I think that means that if a class was using non-bean style and has a field 
>>> called isActive,
>>> then if you create a method for it called isActive, then its property name 
>>> is "active", not "isActive"
>>> (even when set to BOTH_PROPERTY_AND_METHOD or PROPERTY_ONLY).
>>> i.e. It's not exposed as both "active" (from the bean property syntax) and 
>>> "isActive" (from the non-bean style).
>>> 
>>> I hope that's right and all as intended!
>>> 
>>> Cheers,
>>> Simon
>> 
>> 
>> 
>> 
>> --
>> Best regards,
> 
>> Daniel Dekany
> 
> 
> 
> -- 
> Best regards,
> Daniel Dekany

Reply via email to