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.'.

Thursday, September 19, 2013

Regexp regular expression matching in ABAP

 

Hi Folks,
looking around while trying to search an abap pattern in the whole abap repository with the interesting "ABAP_SOURCE_CODE_SCAN" report i realized that SAP has built-in regexp pattern matching features into ABAP.

I had been waiting long time for such a feature.

An overview of the underlying abap syntax can be found looking at the demo source code and is quite simple:

          IF nocase = 'X'.
            FIND REGEX regex IN TABLE result_it IGNORING CASE
                 SUBMATCHES sub1 sub2 sub3 sub4 sub5 sub6.

            IF first = 'X'.
              REPLACE REGEX regex IN TABLE result_it
                      WITH new_marked IGNORING CASE.

            ELSE. " all = 'X'
              REPLACE ALL OCCURRENCES OF REGEX regex IN TABLE result_it
                      WITH new_marked IGNORING CASE.

            ENDIF.
          ELSE. " case = 'X'
            FIND REGEX regex IN TABLE result_it
                 SUBMATCHES sub1 sub2 sub3 sub4 sub5 sub6.

            IF first = 'X'.
              REPLACE REGEX regex IN TABLE result_it
                      WITH new_marked.
            ELSE. " all = 'X'
              REPLACE ALL OCCURRENCES OF REGEX regex IN TABLE result_it
                      WITH new_marked.

            ENDIF.

Here text lines in abap are represente as a "table of string data elements" which is quite common.

If you are interested in regexp there is an interesting tutorial here at
regexp tutorial

The syntax should be posix compliant. i tried some simple stuff and it works just fine.

SAP has released i nice toy test program acually called
DEMO_REGEX_TOY

Here a screen shot



So what does \b(\w+)\s+\1\b mean?

\b is the beginning of the word
\w+ means 1 or more alphanumeric chars
\s+ means 1 or more whitespace chars
\1 means the first subpattern matched
\b means end of the word in that position.

So basically you ask the regexp engine to match
a beginning word made of 1 or more alpha chars wollowed by one or more whitespace chars followed by the first matched subpattern (the (\w+)  ) followed by an ending word.
Funny isn't it?
But quite useful and powerful!