Tuesday, September 24, 2013

how to Clone objects in SAP ABAP



Hi Folks,
this post is about cloning an object in ABAP.

You need to make an exact copy of your object. Duplicating everything contained in the object so that when you change something in the first object you get no effect on the cloned object (caveat: what happens with obj references in the attributes? read on...).

Manually you would implement a method clone which could basically look like this:

method: clone. "returning r_ref type ref to lcl_my_class.

data l_ref type ref to lcl_my_class.
create object l_ref.

*Copy all attributes.
l_ref->a_value = me->a_value.
l_ref->at_table = me->at_table.

*Clone contained objects recursively


r_ref = l_ref.
endmethod.

There is a simple and nice trick to get the job done in a fashion that resembles other programming languages.

Implemente the interface IF_OS_STATE
like this:
CLASS zcl_data_mgr DEFINITION.
  PUBLIC SECTION.
  interfaces IF_OS_CLONE .
 ...


In the method clone implementation of the interface add the following
method IF_OS_CLONE~CLONE.
  SYSTEM-CALL OBJMGR CLONE ME TO RESULT.
endmethod.
 

you can then clone your object with the following single line.

DATA lr_obj type ref to zcl_data_mgr.
lr_obj ?= gr_data_mgr->if_os_clone~clone( ).

Here the result of a test program that demonstrates that cloning clones attributes, but does not clone object references recursively.

The conclusion is that cloning is a nice feature that requires caution when you have objects with a status in the attributes: these do not get cloned but instead their references are copied and thus shared among the clones.





And here the test program coding:

*&---------------------------------------------------------------------*
*& Report  ZZ_test_clone
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT 
ZZ_test_clone.


*----------------------------------------------------------------------*
*       CLASS zcl_contained DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_contained DEFINITION.

  PUBLIC SECTION.
    INTERFACES if_os_clone .

    DATA a_c_value TYPE i.
    DATA a_c_table TYPE STANDARD TABLE OF sflight.

    METHODS: do_something_c.

ENDCLASS.                    "zcl_contained  DEFINITION

*----------------------------------------------------------------------*
*       CLASS zcl_contained  IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_contained  IMPLEMENTATION.

*TODO: TEst this methos and remove the "old fashioned one
  METHOD if_os_clone~clone.

    SYSTEM-CALL OBJMGR CLONE me TO result.

  ENDMETHOD.                    "IF_OS_CLONE~CLONE

  METHOD do_something_c.
    a_c_value = 1.
    SELECT * FROM sflight INTO TABLE a_c_table WHERE carrid = 'SQ'.
  ENDMETHOD.                    "do_something_c

ENDCLASS.                    "zcl_contained  IMPLEMENTATION


*----------------------------------------------------------------------*
*       CLASS zcl_data_mgr DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_data_mgr DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_os_clone .
    DATA a_value TYPE i.
    DATA a_table TYPE STANDARD TABLE OF sflight.
    DATA ar_object TYPE REF TO zcl_contained.

    METHODS: do_something.

ENDCLASS.                    "zcl_data_mgr DEFINITION

*----------------------------------------------------------------------*
*       CLASS zcl_data_mgr  IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_data_mgr  IMPLEMENTATION.

*TODO: TEst this methos and remove the "old fashioned one
  METHOD if_os_clone~clone.

    SYSTEM-CALL OBJMGR CLONE me TO result.

  ENDMETHOD.                    "IF_OS_CLONE~CLONE

  METHOD do_something.
    a_value = 1.
    SELECT * FROM sflight INTO TABLE a_table WHERE carrid = 'LH'.
    CREATE OBJECT ar_object.
    CALL METHOD ar_object->do_something_c.
  ENDMETHOD.                    "do_something

ENDCLASS.                    "zcl_data_mgr  IMPLEMENTATION

START-OF-SELECTION.

  DATA lr_ref type REF TO zcl_data_mgr.

  CREATE OBJECT lr_ref.
  CALL METHOD lr_ref->do_something.

  DATA lr_obj TYPE REF TO zcl_data_mgr.

  lr_obj ?= lr_ref->if_os_clone~clone( ).

  WRITE:/ 'Done.'.