2009 May 13 5:50 PM
Hello,
I have a class which has a hashed table as an attribute. I want to retrieve a line from the table using the key and return a reference to the table line. I want changes to the return value of the method to be directly reflected in the table, as if using a local field symbol. I have tried to approaches, neither of which works.
First, I returned a reference to the local field symbol. This dumps, because after returning from the method call, the target of this reference no longer resides on the stack.
Second, I have tried using an export parameter marked as "pass by reference", i. e. without VALUE(). Strangely, this still seems to give me only a copy of the data.
What is the correct way to proceed?
Illustrative pseudo-code follows.
Thanks, Sebastian
*==============================================================
*Possibility 1: (using references)
DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
METHODS get
IMPORTING
!is_key TYPE zs_key
EXPORTING
!er_vt TYPE REF TO zs_entity.
METHOD get.
FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.
READ TABLE mt_key_value WITH KEY key = is_key ASSIGNING <fs_vt>.
GET REFERENCE OF <fs_vt> INTO er_vt.
ENDMETHOD.
" Client Code:
FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.
CALL METHOD get
EXPORTING
is_key = is_key
IMPORTING
er_vt = lr_vt.
ASSIGN lr_vt->* TO <fs_vt>. " will dump, because the local field symbol
" to which lr_vt points is no longer on the stack
<fs_vt>-value = 'newdata'.
*==============================================================
*Possibility 2: (using a structure passed by reference)
DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
METHODS get
IMPORTING
!is_key TYPE zs_key
EXPORTING
!es_vt TYPE zs_entity.
METHOD get.
FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.
READ TABLE mt_key_map WITH KEY key = is_key ASSIGNING <fs_vt>.
es_vt = <fs_vt>.
ENDMETHOD.
" Client Code:
DATA: ls_vt TYPE zs_entity.
CALL METHOD get
EXPORTING
is_key = is_key
IMPORTING
es_vt = ls_vt.
ls_vt-value = 'newdata'. " will not change the contents of the
" table mt_key_value
Hello,
I have a class which has a hashed table as an attribute. I want to retrieve a line from the table using the key and return a reference to the table line. I want changes to the return value of the method to be directly reflected in the table, as if using a local field symbol. I have tried to approaches, neither of which works.
First, I returned a reference to the local field symbol. This dumps, because after returning from the method call, the target of this reference no longer resides on the stack.
Second, I have tried using an export parameter marked as "pass by reference", i. e. without VALUE(). Strangely, this still seems to give me only a copy of the data.
What is the correct way to proceed?
Illustrative pseudo-code follows.
Thanks, Sebastian
*==============================================================
*Possibility 1: (using references)
DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
METHODS get
IMPORTING
!is_key TYPE zs_key
EXPORTING
!er_vt TYPE REF TO zs_entity.
METHOD get.
FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.
READ TABLE mt_key_value WITH KEY key = is_key ASSIGNING <fs_vt>.
GET REFERENCE OF <fs_vt> INTO er_vt.
ENDMETHOD.
" Client Code:
FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.
CALL METHOD get
EXPORTING
is_key = is_key
IMPORTING
er_vt = lr_vt.
ASSIGN lr_vt->* TO <fs_vt>. " will dump, because the local field symbol
" to which lr_vt points is no longer on the stack
<fs_vt>-value = 'newdata'.
*==============================================================
*Possibility 2: (using a structure passed by reference)
DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
METHODS get
IMPORTING
!is_key TYPE zs_key
EXPORTING
!es_vt TYPE zs_entity.
METHOD get.
FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.
READ TABLE mt_key_map WITH KEY key = is_key ASSIGNING <fs_vt>.
es_vt = <fs_vt>.
ENDMETHOD.
" Client Code:
DATA: ls_vt TYPE zs_entity.
CALL METHOD get
EXPORTING
is_key = is_key
IMPORTING
es_vt = ls_vt.
ls_vt-value = 'newdata'. " will not change the contents of the
" table mt_key_value
2009 May 13 7:29 PM
In the first approch, try to change the exporting parameter type REF TO DATA.
Try like:
*----------------------------------------------------------------------*
CLASS lcl_test DEFINITION.
PUBLIC SECTION.
DATA: t_mara TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.
METHODS:
constructor,
get
IMPORTING
if_matnr TYPE matnr
EXPORTING
ea_mara TYPE REF TO data.
ENDCLASS. "lcl_test DEFINITION
START-OF-SELECTION.
DATA: lo_test TYPE REF TO lcl_test,
lr_data TYPE REF TO data.
FIELD-SYMBOLS: <fa_mara> TYPE ANY,
<f_field> TYPE ANY.
CREATE OBJECT lo_test.
lo_test->get(
EXPORTING
if_matnr = '000000000077000000' " << Replace Your Material
IMPORTING
ea_mara = lr_data ).
ASSIGN lr_data->* TO <fa_mara>.
ASSIGN COMPONENT 'ERSDA' OF STRUCTURE <fa_mara> TO <f_field>.
<f_field> = space.
WRITE: 'Done'.
*----------------------------------------------------------------------*
CLASS lcl_test IMPLEMENTATION.
METHOD constructor.
SELECT * INTO TABLE t_mara
FROM mara
UP TO 10 ROWS.
ENDMETHOD. "constructor
METHOD get.
FIELD-SYMBOLS: <lfs_mara> LIKE LINE OF me->t_mara.
READ TABLE me->t_mara ASSIGNING <lfs_mara> WITH KEY matnr = if_matnr.
GET REFERENCE OF <lfs_mara> INTO ea_mara.
ENDMETHOD. "get
ENDCLASS. "lcl_test IMPLEMENTATION
Regards,
Naimesh Patel
2009 May 13 7:43 PM
Hi Seb,
I imagine you will get lots of responses on how to do this.
I just wanted to point out that what you are trying to do breaks one of the underlying principles of OO design - namely "encapsulation".
You should not allow the modification of a class attribute directly, rather you should only allow attribute changes by calling the appropriate method of the class.
Cheers
Graham Robbo
2009 May 14 7:51 AM
Dear Sebastian ,
My suggesstion is as follows:
Since the table is an hashed table , try to export the hash algorithm instead of a field symbol to a record.
If we can export the hash algorithm , then we can get access to any table line(record) of the hashed table.
I hope , this idea works.
Thanks and Regards ,
Debojyoti chanda.
2009 May 14 9:10 AM
Thanks Naimesh. Your code is structurally identically to what I posted (taking away the type information from the reference is not significant) You made me see that I actually made another mistake which I did not include in my example code - I apologize for that. My mistake occurred when I inserted a new line in the table. I simply returned a reference to the inserted structure instead of re-reading the table to obtain a reference to the new line. Thank you for your help.
@Graham: Encapsulation is not a concern. I did not state in my post that the get-method is private. The reference never leaves the enclosing class.
2009 May 14 11:05 AM
Don't agree with you - but anyway...
READ TABLE me->t_mara REFERENCE INTO ea_mara WITH KEY matnr = if_matnr.
Cheers
Graham Robbo
2009 May 15 9:47 AM
I'd say only use setters and getters for public access to attributes. Maybe protected. But private - I don't see the need!
matt