【问题标题】:CALL METHOD and method chainingCALL METHOD 和方法链
【发布时间】:2019-01-23 14:49:14
【问题描述】:

对于 CALL METHOD - Static Method Call (Obsolete),ABAP 关键字文档说:“如果 CALL METHOD 用于独立方法调用,则不可能进行链式方法调用......”

尽管如此,以下内容在 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 专家。

【问题讨论】:

  • 你能把链接添加到文档吗?
  • 另外一个注意事项:为什么不设置一个小型的 NetWeaver 并让 ABAP 自己的解析器进行解析呢?将解析器公开为 REST 服务并将 Java 连接到它。
  • @Florian。一个吸引人的想法,但对我们来说不可行。我们的工具已经很老了,早于提到的功能。因此,使用它意味着完全重写该工具。我们的工具可以在本地运行而无需连接到 SAP 系统。当然,我们所做的不仅仅是解析,因此需要控制解析树的外观。
  • 与问题无关,关于“解析器”免责声明,你看过用 TypeScript 编写的 abaplint 吗?
  • 我们的工具 smartTool 已经开发了 10 多年,使我们 (smartShift) 能够帮助主要的 SAP 客户完成他们的传统转型项目。 abaplint 有一些相似之处,但我们在这里谈论的是不同的球场

标签: abap


【解决方案1】:

附录2月23日,Florian在cmets中给出了正确答案:“我向docu团队报告了这个错误,他们回答说已经报告了,他们在最新版本中更正了它。新的声明是: "使用不带圆括号的第二个变体,不能进行链式方法调用,也不能使用运算符 NEW 和 CAST。""

我把我原来的答案放在下面(顺便说一下,我认为现在在CALL METHOD static_meth... 中,术语“独立方法调用”是指“static_meth”部分,所以它指的是两组构造,因此我的答案是不准确的,SAP 的答案是 100% 正确的)


如我所见,文档说“独立方法调用”一词指的是这些被声明为过时的构造(注意括号的使用):

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.

术语“独立方法调用”并不指这些结构:

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( ) 无效)。

我的结论:您应该阅读“如果 CALL METHOD 用于独立方法调用,则不可能进行链式方法调用......”

Florian 和 SAP 的结论:在下面的 cmets 中,Florian 已询问 SAP 支持,并指出 SAP 应在文档的下一个正式版本中使用哪个确切的句子


ADDENDUM(如果您错误地认为文档页面是关于“静态方法”的,请阅读它,我希望我会澄清它不是)。

这个问题的答案证明documentation "CALL METHOD - Static Method Call (Obsolete)"相当混乱

文档标题:这里的“静态方法调用”是指“静态方法调用”,而不是“静态方法调用”(而在其他地方可能有这个含义)。如果我们可以在书面语言中添加括号,那将分别给出这两种可能性:

  • 静态(方法调用):方法的静态调用(无论此方法是“静态”或“实例”类型;我们可以对实例方法进行静态调用)
  • (静态方法)调用:静态方法的调用

定义:

  • 静态调用:类、接口或方法名称在源代码中被“硬编码”为符号,而不是文本字面量,以便编译器知道它们(例如,CALL METHOD class=>method.)。相反,动态调用意味着名称通过变量传递,这些变量仅在运行时才知道(例如,DATA classvar TYPE seoclsname VALUE 'CL_ABAP_TYPEDESCR'. CALL METHOD (classvar)=>(methodvar).)另一个documentation page很好地表明“静态方法调用”与“动态方法调用”相对”,它从不谈论“静态和实例方法”,只谈论“静态方法调用”和“动态方法调用”。
  • 静态方法:使用CLASS-METHODS 声明的方法。例如,静态调用可以是cl_ixml=>create( ),动态调用可以是DATA classvar TYPE seoclsname VALUE 'CL_IXML'. CALL METHOD (classvar)=>create

文档中的一些东西也让我感到困惑,是使用术语“静态方法”和仅基于静态方法的示例,因为实际上文档页面是关于“静态调用”,而不是静态方法(实例方法可以已使用):

  • 语法CALL METHOD { static_meth( ) | static_meth( a ) | ...:这里的“static_meth”是什么意思?事实上,“static_meth”并不意味着它是静态方法,而是静态方法调用上下文中的任何方法。如果您查看有关“static calls”和“dynamic calls”的文档页面,您将看到语法分别为static_meth( ) ...CALL METHOD dynamic_meth ...
  • 示例 :在三个调用中再次使用了一个静态方法,所有三个具有相同的确切含义但用不同的语法编写,以证明前两个调用已过时,只有第三个调用被推荐。事实上,所有三个示例都应该更好地使用实例方法以避免混淆!

【讨论】:

  • 我看不出第一组和第二组之间有什么区别。你能解释一下吗?
  • 这不是文档中的错误。文档说明了静态方法调用(由CLASS-METHOD 定义)。该示例有一个普通方法,需要引用要调用的对象。
  • 感谢您解决这个问题!我向文档团队报告了这个错误,他们回答说已经报告了,他们在最新版本中更正了它。新的声明是:“使用没有圆括号的第二个变体,链式方法调用是不可能的,也不能使用运算符 NEW 和 CAST。”
  • @UlrichScholz,Sandra 的回答是正确的——虽然有点冗长 ;-)——它应该是被接受的。与 docu 团队取得联系非常简单:在您的 SAP 系统中打开 SAP 语言帮助中的文章,然后在右上角点击“反馈”链接。它会创建一封电子邮件,您现在可以填写您的问题。他们通常会迅速回复并通过电子邮件与您联系。请注意,已发布的网络版文档 (help.sap.com) 不包含该链接。
  • @Suncatcher 希望动态方法调用只有一个含义(动态“方法调用”,即没有“动态方法”),所以是的,唯一的可能性是调用方法。并且静态“方法调用”(不是“静态方法”调用)应该在没有 CALL METHOD 的情况下完成,因为这个变体已经过时,所以现在使用 instance->method( ... ) 或 class=>method( ... )
【解决方案2】:

首先,方法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.

【讨论】:

  • 贾格尔,感谢您的回答。这里有几件事。首先,SAP ABAP 在两个意义上使用“静态”w.r.t。方法调用。您在非实例访问的意义上阅读它,即访问静态类组件。虽然我不能 100% 确定,但我想,预期的含义是非动态的,因为文档给出的 CALL 方法的另一个非过时变体是 CALL METHOD dynamic_meth 的变体。然后,对我来说 class_parent=>m1_static( )->m1_static( ) 将有资格作为方法链接。没有把握。最后,“没有人理智”。来吧,这是 ABAP :-)
  • 我同意@ulrichscholz,文档页面不是关于静态方法,而是关于方法的静态调用。我已经扩展了我的答案来证明它(这并不容易,花了我一些时间!)
  • @SandraRossi 这个神秘的静态方法调用会是什么?哪有这回事。只需查看文档中的示例即可。他们都有CLASS-METHODS
  • @Jagger 我已在答案的第 1 部分中详细解释了所有内容,并附有 ABAP 文档中“静态调用”的链接,以及示例的解释。
【解决方案3】:

文档中的一个错误。我向docu团队报告了它,他们回答说已经报告了,他们在最新版本中更正了它。

新的语句是:

使用没有圆括号的第二个变体,链式方法调用 是不可能的,也不能使用运算符 NEW 和 CAST。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2022-11-09
    • 2023-03-27
    • 2022-01-08
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多