You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "OC (Jira)" <ji...@apache.org> on 2025/03/29 17:27:00 UTC
[jira] [Comment Edited] (GROOVY-11591) safe call evaluates arguments
[ https://issues.apache.org/jira/browse/GROOVY-11591?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17939434#comment-17939434 ]
OC edited comment on GROOVY-11591 at 3/29/25 5:26 PM:
------------------------------------------------------
Myself, I haven't found any relevant documentation (perhaps there is some and I've missed it).
The potential side-effects are my primary concern (efficiency with more complex arguments secondary).
In my personal opinion, regardless the compilation mode, whenever _null_ is the receiver, the arguments should _never_ be evaluated — neither before a safe call „empty operation“, nor before NPE if safe call is not used. In my personal opinion, _foo?.bar(...)_ should be functionally equivalent to {_}foo==null?null:foo.bar(...){_}.
(It is still well possible I overlook some reasons why this might be either wrong, or at least technically unfeasible.)
was (Author: oc):
Myself, I haven't found any relevant documentation (perhaps there is some and I've missed it).
The potential side-effects are my primary concern (efficiency with more complex arguments secondary).
In my personal opinion, regardless the compilation mode, whenever _null_ is the receiver, the arguments should _never_ be evaluated — neither before a safe call „empty operation“, nor before NPE if safe call is not used. In my personal opinion, _foo?.bar(...)_ should be functionally equivalent to {_}foo==nil?nil:foo.bar(...){_}.
(It is still well possible I overlook some reasons why this might be either wrong, or at least technically unfeasible.)
> safe call evaluates arguments
> ------------------------------
>
> Key: GROOVY-11591
> URL: https://issues.apache.org/jira/browse/GROOVY-11591
> Project: Groovy
> Issue Type: Bug
> Reporter: OC
> Priority: Minor
>
> A safe method call first evaluates method's arguments, and only then trashes the call. It would seem to me much better if the arguments were not evaluated in this case (precisely same way as if we used the java-like “if (obj) obj.whatever...” approach instead of the safe call).
> Based on Jochen insight, what probably happens is
> * push arguments on stack
> * push receiver on stack
> * write jmp if null
> * write method call
> * jmp to after call
> * marker for null case
> * remove elements from stack
> * push null
> * marker for after call
> Testable e.g., by
> {code:java}
> 1040 ocs /tmp> <q.groovy
> class qq {
> def foo(String s) {
> println "foo called!"
> s
> }
> def bar(String s) {
> println "bar: $s"
> }
> }
> null?.bar(new qq().foo('Oops!'))
> 1041 ocs /tmp> /usr/local/groovy-4.0.25/bin/groovy q
> foo called!
> 1042 ocs /tmp> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)