does a `Property` convention mutate the original p...
# community-support
c
does a
Property
convention mutate the original property, or does it return a new one? I'm definitely writing code like it returns a new one...
t
It works like a
set()
with lower priority (won't change the property value if one has already been
set()
)
c
so, in theory though it mutates. I guess I worded that poorly...
c
I mean to say that the Property object is mutated, not the value
right...
well, who reads documentation. not me apparently 😕, sorry
v
If it would return a new instance, it would largely work against the principle for which `Property`s were introduced.
If it would return a new instance, it would largely work against the principle for which `Property`s were introduced. The sense is, that you do not change the property (as in field), but set the value of the one read-only
Property
instance. So if
convention
would return a new instance, that would be counter-productive. Also typically you set those conventions from the plugin that registers a task or extension.
👍 2
c
right, but what I've seen is I set up the empty
Property
and then call convention... so the property is kind of set up first. I'm not doing something like
Property.convention("...")
to create them, gradle is injecting or whatever. since I'm always chaining then I've basically set them up right before extracting, so from an API perspective... I wasn't really able to intuit whether and what kind of builder. (I mean
prop.convention("foo").get()
doesn't intuit that convention is mutating, and we aren't really supposed to be calling get most of the time. I should have read the docs though...
Property.convention(...)
would be nice 😛 and can I get a simple
Provider
interface? haven't quite figured out why creating a
Provider
requires gradle to do it... but these are other topics entirely
v
Usually you wouldn't set convention right before getting the value, for that you can simply do
getOrElse
. As I said, usually you set the convention in the plugin that registers the according task or extension, so that every consumer sees that convention if no explicit value was set.
Calling
convention
at execution time before getting the property might even be an anti-pattern, as it changes the configuration actually.
c
when you're doing it in the plugin right before you access it...
when in the plugin do you set it?
v
Usually when I register the task or extension. And nowhere in the plugin I get a property value, because that only brings the same problems
afterEvaluate
brings, ordering problems and race conditions.
c
so you don't use convention plugins? build-logic/buildSrc? that's cool
must be hard to create a plugin that does anything if the plugin can't use the values of its extensions to do work
v
Why should I not use convention plugins? And no, it is no problem at all to write plugins that don't directly use those values.
c
then why have the values if nothing ever uses them?
v
As I explained previously,
Property
is for evaluation at execution time. Whenever you evaluate at configuration time, you create ordering problems and race conditions just like if you would use
afterEvaluate
. `Property`s are for wiring together and only evaluated at execution time. If I need something at configuration time, I don't make it a
Property
, but a function parameter, or nested one level so that the setting is wrapped in a function call.
then why have the values if nothing ever uses them?
Why noone?
You wire extension properties to task properties and at execution time you get the value in the task.
c
oh, I think I know what you're talking about... you're obsessing over the
.get()
which I also could have used
.map
but since I'm working on configuring publishing I'm working with a bunch of stuff which isn't lazy
point more being that I always am adding the convention in the same spot where I'm making use (lazy or otherwise) of the property
☝️ 1
so even if it's
something.set(extension.myprop.convention("foo").map { } )
that's always where it ends up being... right before its use
so the usage in my head is non obvious that it mutates when I'm always writing it like that
v
Yeah, well, that's just a usual builder / call chain pattern.
c
right, but it's also a functional pattern
part of that is builder, part of it is functional
v
Yep, you can never differentiate those two from is usage
c
most builders have some kind of
build()
anyways, I get how it works now
or they have
Builder
in the class name
most (tm) 😉
v
Yeah, its not exactly builder, just saying there your also get this returned. It is call chain pattern as mentioned :-)
c
and not even all builders are mutable, so anyways, that's my point of confusion. It mostly looks like functional code
v
And I object to that "most", I know many builder pattern applications where the class is not named ...Builder and the method not named build. 🤷‍♂️
c
you can object, most only requires 50.1% 😉
v
So? ;-)
c
and I'm only talking java land to be fair, maybe only java
to excluse the other jvm langs
v
Me too mostly
c
because I have no idea what scala/groovy/etc are up to
then there's the question of whether everything that uses a fluent api constitutes a builder
v
No
c
assertj for example
anyways, this'd be hard argument to win 😄
and would probably require access to massive amounts of private code, and having that fluent argument
when does pattern X evolve into Y, when does an observer become pub sub
v
It's pointless anyway. Even builder pattern, call chain pattern, fluent API, all not necessarily require that the same instance is returned, just that the type is the same, but could as well be a new instance
c
I've never heard of "call chain pattern"
and yes, of course, and that's why I asked, but should've read the docs closer
closer meaning "at all" (looks like javadoc is visible in idea again)
v
Call it fluent API if you prefer :-)
c
guess I should have said interface? but meh, the api is fluent. fowler is always right 😛 https://martinfowler.com/bliki/FluentInterface.html
I have heard the term call chaining, just never as a "pattern". Anyways, I'm gonna move on, I made progress today on my publishing stuff, improving that API