CALL METHOD 和方法链
CALL METHOD and method chaining
对于 CALL METHOD - 静态方法调用(过时),ABAP 关键字文档说:"If CALL METHOD is used for the standalone method call, no chained method calls are possible ..."
尽管如此,下面的代码在 7.40 系统上运行良好。这不是独立方法调用的示例吗?否则,我哪里错了?
REPORT ZUTEST3.
CLASS class_parent Definition.
PUBLIC Section.
METHODS m1 returning value(r) type ref to class_parent.
ENDCLASS.
CLASS class_parent Implementation.
Method m1.
create object r.
write / 'm1'.
EndMethod.
ENDCLASS.
start-of-selection.
data cl type ref to class_parent.
CREATE OBJECT cl.
CALL METHOD cl->m1( )->m1( ).
编辑:免责声明
我们正在 Java 中编写一个工具来解析和转换 ABAP 代码。特别是,我们无意编写新的 ABAP 代码。但相反,我们的工具必须处理所有 ABAP,甚至是过时的语句和晦涩的语法变体。此外,我想说明一下,我不是 ABAP 专家。
2 月 23 日的附录,Florian 在评论中给出了正确的答案:"I reported the bug to the docu team and they answered that it has already been reported and they corrected it in the latest version. The new statement is: "对于没有圆括号的第二个变体,链式方法调用是不可能的,运算符 NEW 和 CAST无法使用。""
我把我原来的答案放下面(顺便说一句,我现在认为在CALL METHOD static_meth...
中,术语"standalone method call"指的是"static_meth"部分,所以它指的是两个结构组,因此我的回答不准确,而 SAP 的回答是 100% 正确)
正如我所看到的,文档说术语 "standalone method call" 指的是这些构造(注意括号的使用),它们被声明为已过时:
CALL METHOD method( ).
CALL METHOD method( 25 ).
CALL METHOD method( a = 1 ).
CALL METHOD method( EXPORTING a = 1 ).
CALL METHOD instance->method( ).
CALL METHOD class=>method( ).
etc.
术语“"standalone method call" 不指代这些结构 :
CALL METHOD method.
CALL METHOD method EXPORTING a = 1.
CALL METHOD instance->method.
CALL METHOD class=>method.
etc.
我猜想 CALL METHOD cl->m1( )
属于第一组结构,所以 文档中有错误。
可能缺少 not,因为它应该应用于第二组构造(例如,CALL METHOD method->method( )
无效)。
我的结论:你应该阅读"If CALL METHOD is not used for the standalone method call, no chained method calls are possible ..."
Florian 和 SAP 的结论:在下面的评论中,Florian 已询问 SAP 支持并指出 SAP 应该在下一个正式版本的文档中使用哪个确切的句子
ADDENDUM(如果你认为文档页面是关于"static methods"的错误,请阅读它,我希望我能澄清它不是)。
这个问题的答案证明documentation "CALL METHOD - Static Method Call (Obsolete)"是相当混乱。
文档标题:这里"static method call"的意思是"static call of methods",不是"call of static methods"(其他地方可能是这个意思) .如果我们能在书面语中加上括号,那将分别给出这两种可能性:
- static (method call) : 方法的静态调用(不管这个方法是"static"还是"instance"类型;我们可以有一个static调用实例方法)
- (static method) call : 静态方法的调用
定义:
- static call : class, 接口或方法名称是 "hardcoded" 作为源代码中的符号,而不是文本文字,因此它们是编译器已知(例如,
CALL METHOD class=>method.
)。相反,动态调用意味着名称通过变量传递,这些变量仅在运行时已知(例如,DATA classvar TYPE seoclsname VALUE 'CL_ABAP_TYPEDESCR'. CALL METHOD (classvar)=>(methodvar).
)另一个 documentation page 很好地表明 "static method call" 与"dynamic method call",它从不谈论"static and instance methods",只谈论"static method call"和"dynamic method call"。
- 静态方法 : 用
CLASS-METHODS
声明的方法。例如,静态调用可以是 cl_ixml=>create( )
,动态调用可以是 DATA classvar TYPE seoclsname VALUE 'CL_IXML'. CALL METHOD (classvar)=>create
.
文档中的一些东西也让我感到困惑,是术语 "static method" 的使用和仅基于静态方法的示例,因为实际上文档页面是关于 "static call",而不是静态方法(可以使用实例方法):
- 语法 :
CALL METHOD { static_meth( ) | static_meth( a ) | ...
: 这里的 "static_meth" 是什么意思?事实上 "static_meth" 并不意味着它是一个静态方法,而是在 静态方法调用 的上下文中的任何方法。如果您查看有关“static calls" and "dynamic calls”的文档页面,您会看到语法分别为 static_meth( ) ...
和 CALL METHOD dynamic_meth ...
- Example : 三个调用中再次使用静态方法,所有三个具有相同的确切含义但使用不同的语法编写,以证明前两个调用已经过时了,只推荐第三种。事实上,这三个示例最好都使用实例方法来避免混淆!
首先,您的示例中的方法 m1
不是静态的,文档中的引文说它是关于静态方法 (CLASS-METHOD
)。
唯一可能的可能就是这个例子。
REPORT zutest3.
CLASS class_parent DEFINITION.
PUBLIC SECTION.
METHODS m1 RETURNING VALUE(r) TYPE REF TO class_parent.
CLASS-METHODS m1_static RETURNING VALUE(r) TYPE REF TO class_parent.
ENDCLASS.
CLASS class_parent IMPLEMENTATION.
METHOD m1.
CREATE OBJECT r.
WRITE / 'm1'.
ENDMETHOD.
METHOD m1_static.
CREATE OBJECT r.
WRITE / 'm2'.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
* this seems to be possible but no one sane calls a static method on an object reference
CALL METHOD class_parent=>m1_static( )->m1_static( ).
* the following two are not possible and will not compile either
* CALL METHOD class_parent=>m1_static( )=>m1_static( ).
* class_parent=>m1_static( )=>m1_static( ).
第二个 CALL METHOD
语句在这种情况下只是一个冗余,它的作用只是提供信息。
这两个是等价的
CALL METHOD cl->m1( ).
cl->m1( ).
类似于这个
DATA i TYPE i.
COMPUTE i = i + 1.
i = i + 1.
文档中的错误。我向docu团队报告了,他们回答说已经报告了,他们在最新版本中更正了。
新声明为:
With the second variant without round brackets, chained method calls
are not possible and the operators NEW and CAST cannot be used.
对于 CALL METHOD - 静态方法调用(过时),ABAP 关键字文档说:"If CALL METHOD is used for the standalone method call, no chained method calls are possible ..."
尽管如此,下面的代码在 7.40 系统上运行良好。这不是独立方法调用的示例吗?否则,我哪里错了?
REPORT ZUTEST3.
CLASS class_parent Definition.
PUBLIC Section.
METHODS m1 returning value(r) type ref to class_parent.
ENDCLASS.
CLASS class_parent Implementation.
Method m1.
create object r.
write / 'm1'.
EndMethod.
ENDCLASS.
start-of-selection.
data cl type ref to class_parent.
CREATE OBJECT cl.
CALL METHOD cl->m1( )->m1( ).
编辑:免责声明
我们正在 Java 中编写一个工具来解析和转换 ABAP 代码。特别是,我们无意编写新的 ABAP 代码。但相反,我们的工具必须处理所有 ABAP,甚至是过时的语句和晦涩的语法变体。此外,我想说明一下,我不是 ABAP 专家。
2 月 23 日的附录,Florian 在评论中给出了正确的答案:"I reported the bug to the docu team and they answered that it has already been reported and they corrected it in the latest version. The new statement is: "对于没有圆括号的第二个变体,链式方法调用是不可能的,运算符 NEW 和 CAST无法使用。""
我把我原来的答案放下面(顺便说一句,我现在认为在CALL METHOD static_meth...
中,术语"standalone method call"指的是"static_meth"部分,所以它指的是两个结构组,因此我的回答不准确,而 SAP 的回答是 100% 正确)
正如我所看到的,文档说术语 "standalone method call" 指的是这些构造(注意括号的使用),它们被声明为已过时:
CALL METHOD method( ).
CALL METHOD method( 25 ).
CALL METHOD method( a = 1 ).
CALL METHOD method( EXPORTING a = 1 ).
CALL METHOD instance->method( ).
CALL METHOD class=>method( ).
etc.
术语“"standalone method call" 不指代这些结构 :
CALL METHOD method.
CALL METHOD method EXPORTING a = 1.
CALL METHOD instance->method.
CALL METHOD class=>method.
etc.
我猜想 CALL METHOD cl->m1( )
属于第一组结构,所以 文档中有错误。
可能缺少 not,因为它应该应用于第二组构造(例如,CALL METHOD method->method( )
无效)。
我的结论:你应该阅读"If CALL METHOD is not used for the standalone method call, no chained method calls are possible ..."
Florian 和 SAP 的结论:在下面的评论中,Florian 已询问 SAP 支持并指出 SAP 应该在下一个正式版本的文档中使用哪个确切的句子
ADDENDUM(如果你认为文档页面是关于"static methods"的错误,请阅读它,我希望我能澄清它不是)。
这个问题的答案证明documentation "CALL METHOD - Static Method Call (Obsolete)"是相当混乱。
文档标题:这里"static method call"的意思是"static call of methods",不是"call of static methods"(其他地方可能是这个意思) .如果我们能在书面语中加上括号,那将分别给出这两种可能性:
- static (method call) : 方法的静态调用(不管这个方法是"static"还是"instance"类型;我们可以有一个static调用实例方法)
- (static method) call : 静态方法的调用
定义:
- static call : class, 接口或方法名称是 "hardcoded" 作为源代码中的符号,而不是文本文字,因此它们是编译器已知(例如,
CALL METHOD class=>method.
)。相反,动态调用意味着名称通过变量传递,这些变量仅在运行时已知(例如,DATA classvar TYPE seoclsname VALUE 'CL_ABAP_TYPEDESCR'. CALL METHOD (classvar)=>(methodvar).
)另一个 documentation page 很好地表明 "static method call" 与"dynamic method call",它从不谈论"static and instance methods",只谈论"static method call"和"dynamic method call"。 - 静态方法 : 用
CLASS-METHODS
声明的方法。例如,静态调用可以是cl_ixml=>create( )
,动态调用可以是DATA classvar TYPE seoclsname VALUE 'CL_IXML'. CALL METHOD (classvar)=>create
.
文档中的一些东西也让我感到困惑,是术语 "static method" 的使用和仅基于静态方法的示例,因为实际上文档页面是关于 "static call",而不是静态方法(可以使用实例方法):
- 语法 :
CALL METHOD { static_meth( ) | static_meth( a ) | ...
: 这里的 "static_meth" 是什么意思?事实上 "static_meth" 并不意味着它是一个静态方法,而是在 静态方法调用 的上下文中的任何方法。如果您查看有关“static calls" and "dynamic calls”的文档页面,您会看到语法分别为static_meth( ) ...
和CALL METHOD dynamic_meth ...
- Example : 三个调用中再次使用静态方法,所有三个具有相同的确切含义但使用不同的语法编写,以证明前两个调用已经过时了,只推荐第三种。事实上,这三个示例最好都使用实例方法来避免混淆!
首先,您的示例中的方法 m1
不是静态的,文档中的引文说它是关于静态方法 (CLASS-METHOD
)。
唯一可能的可能就是这个例子。
REPORT zutest3.
CLASS class_parent DEFINITION.
PUBLIC SECTION.
METHODS m1 RETURNING VALUE(r) TYPE REF TO class_parent.
CLASS-METHODS m1_static RETURNING VALUE(r) TYPE REF TO class_parent.
ENDCLASS.
CLASS class_parent IMPLEMENTATION.
METHOD m1.
CREATE OBJECT r.
WRITE / 'm1'.
ENDMETHOD.
METHOD m1_static.
CREATE OBJECT r.
WRITE / 'm2'.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
* this seems to be possible but no one sane calls a static method on an object reference
CALL METHOD class_parent=>m1_static( )->m1_static( ).
* the following two are not possible and will not compile either
* CALL METHOD class_parent=>m1_static( )=>m1_static( ).
* class_parent=>m1_static( )=>m1_static( ).
第二个 CALL METHOD
语句在这种情况下只是一个冗余,它的作用只是提供信息。
这两个是等价的
CALL METHOD cl->m1( ).
cl->m1( ).
类似于这个
DATA i TYPE i.
COMPUTE i = i + 1.
i = i + 1.
文档中的错误。我向docu团队报告了,他们回答说已经报告了,他们在最新版本中更正了。
新声明为:
With the second variant without round brackets, chained method calls are not possible and the operators NEW and CAST cannot be used.