Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

DEFAULT parameter in method definition

nomssi
Active Contributor
0 Kudos

Hello everybody,

I do not understand why the following code will lead to a syntax error:

Within a static method, you can only access class attributes without further specifications.

CLASS lcl_range DEFINITION.
  PUBLIC SECTION.
    DATA: mv_start TYPE date,
          mv_stop TYPE date.

    METHODS:
      create_copy
        IMPORTING iv_start TYPE date DEFAULT mv_start
                  iv_stop TYPE date DEFAULT mv_stop
        RETURNING VALUE(ro_range) TYPE REF TO lcl_range.

ENDCLASS.

Replacing the DATA definition with CLASS-DATA will work, but I do not want a static attribute.

I want to be able to clone an object

best regards

1 ACCEPTED SOLUTION

MarcinPciak
Active Contributor
0 Kudos

I think this is because, static attributes exist even if no objects were created for a class. So you can set default parameter to this static attribute. It will then hold some value already assinged to that static parameter. So when you call you method, DEFAULT parameter will be set to correct value.

Here, however you have DEFAULT set to the instance attributes, which exists only at object creation. You could try changing the DEFAULT values to static value like


iv_start TYPE date DEFAULT '20100316'
                  iv_stop TYPE date DEFAULT '99991231'

So now it is assured that your parameters during method call will receive some default value.

Regards

Marcin

10 REPLIES 10

MarcinPciak
Active Contributor
0 Kudos

I think this is because, static attributes exist even if no objects were created for a class. So you can set default parameter to this static attribute. It will then hold some value already assinged to that static parameter. So when you call you method, DEFAULT parameter will be set to correct value.

Here, however you have DEFAULT set to the instance attributes, which exists only at object creation. You could try changing the DEFAULT values to static value like


iv_start TYPE date DEFAULT '20100316'
                  iv_stop TYPE date DEFAULT '99991231'

So now it is assured that your parameters during method call will receive some default value.

Regards

Marcin

nomssi
Active Contributor
0 Kudos

Thanks Marcin.

Neither the method nor the data are static: I would expect the instance level attributes MV_START and MV_STOP to be visible and be allowed as replacement parameters. From the ABAP help:

While a formal parameter with the addition OPTIONAL is initialized according to its type, a formal parameter with addition DEFAULT copies the value and type of the replacement parameter def1 def2 .... As a replacement parameter def1 def2 ..., you can specify any appropriate data object that is visible at this position.

I could verify that the DEFAULT value is copied at run-tine from for a global or static variable. Why should a limitation exist for instance attibutes ? It seems like an undocumented limitation of ABAP.

best regards,

Jacques Nomssi Nzali

0 Kudos

Hi,

you can't even do this in SE24. I guess that the reason for this is in how cosntructors are called in case of inheritance. I am not sure about this and they might be other technical reasons for this. Here is a quote from ABAP documentation.

The instance constructor of a subclass is split into two parts by the [CALL METHOD] SUPER->CONSTRUCTOR call, which is required from a syntactical point of view. In the statements before the call, the constructor behaves like a static method. This means it cannot access the instance attributes of its class.

So in case you define a subclass from your class lcl_range and you would like to call your method create_copy before super->cosntructor( ) then you would get into troubles because it can't access attributes of it's class.

Cheers

0 Kudos

Hi,

I think that by saying

As a replacement parameter def1 def2 ..., you can specify any appropriate data object that is visible at this position.

SAP means that def1 and def2 must be data objects . So we could use some global data objects from the program to fill that default value, like in the code below


PARAMETERS: def_par1 TYPE date,
            def_par2 TYPE date.

CLASS lcl_range DEFINITION.
  PUBLIC SECTION.
    DATA: mv_start TYPE date,
          mv_stop TYPE date.

    METHODS:
      create_copy
        IMPORTING iv_start TYPE date DEFAULT def_par1
                  iv_stop TYPE date DEFAULT def_par2
        RETURNING value(ro_range) TYPE REF TO lcl_range.

ENDCLASS.                 


CLASS lcl_range IMPLEMENTATION.
  METHOD create_copy.
    WRITE: 'Default parameters are:', def_par1, def_par2.
  ENDMETHOD.                  
ENDCLASS.                    

START-OF-SELECTION.
  DATA: r_range TYPE REF TO lcl_range.

  CREATE OBJECT r_range.
  r_range->create_copy( ).

But such coding is ugly from encapsulation point of view (accessing global data objects from the class itself). So alternative way is, as said before, using static attributes or constants. These are kind of visible data object they mention about. I think this is the only approach.

Don't know exact reason behind this, maybe the one Martin suggested.

Regards

Marcin

nomssi
Active Contributor
0 Kudos

Hi,

I continue to think this is an error because

1) the error message is, well, wrong: there are no static objects here

2) there is a work around: I can define the parameter as OPTIONAL and check it with IF ... SUPPLIED.

I will submit an OSS message. Thanks for your comments.

best regards,

Jacques Nomssi Nzali

CLASS lcl_range DEFINITION.
  PUBLIC SECTION.
    DATA: mv_start TYPE date,
          mv_stop TYPE date.

    METHODS constructor
      IMPORTING iv_start TYPE date
                iv_stop TYPE date.
    METHODS create_copy
        IMPORTING iv_start TYPE date OPTIONAL
                  iv_stop TYPE date OPTIONAL
        RETURNING VALUE(ro_range) TYPE REF TO lcl_range.
ENDCLASS.


CLASS lcl_range IMPLEMENTATION.

  METHOD constructor.
    super->constructor( ).
    mv_start = iv_start.
    mv_stop = iv_stop.
  ENDMETHOD.

  METHOD create_copy.
    DATA lv_start TYPE date.
    DATA lv_stop TYPE date.

    WRITE:/ 'Called with START = ',  iv_start, ' STOP=',  iv_stop.
    IF iv_start IS NOT SUPPLIED.
      lv_start = mv_start.
    ELSE.
      lv_start = iv_start.
    ENDIF.
    IF iv_stop IS NOT SUPPLIED.
      lv_stop = mv_stop.
    ELSE.
      lv_stop = iv_stop.
    ENDIF.
    WRITE:/ 'Updated to START = ',  lv_start, ' STOP=',  lv_stop.
    CREATE OBJECT ro_range
      EXPORTING iv_start = lv_start
                iv_stop = lv_stop.
  ENDMETHOD.

ENDCLASS.

DATA go_2009_range TYPE REF TO lcl_range.
DATA go_copy TYPE REF TO lcl_range.

START-OF-SELECTION.
  CREATE OBJECT go_2009_range
    EXPORTING iv_start = '20090101'
              iv_stop = '20091221'.
* Clone
  go_copy = go_2009_range->create_copy( ).
* Extend range to end of 2010
  go_copy = go_2009_range->create_copy( iv_stop = '20101231' ).
* New start date: May 1st 2009
  go_copy = go_2009_range->create_copy( iv_start = '20090501' ).

0 Kudos

Definitely, the message is confusing. Please keep up posted.

Thanks.

nomssi
Active Contributor
0 Kudos

Hello everybody,

from my OSS message:

1) DEFAULT parameter can only be constant or static

2) the error message is nonsense.

So nothing new here, but at least it is from SAP.

best regards,

Jacques Nomssi Nzali

Former Member
0 Kudos

Hi Jacques,

Definitely an interesting example, so thanks for bringing that up. I'm not sure if I fully understand Marcin's posting, so I might repeat to some degree what he said...

So the error message complains about invalid data access within a static method, even though the error occurs in instance method create_copy. So the ABAP documentation claims (see [here|http://help.sap.com/abapdocu_70/en/ABAPMETHODS_PARAMETERS.htm]):

While a formal parameter with the addition OPTIONAL is initialized according to its type, a formal parameter with addition DEFAULT copies the value and type of the replacement parameter def1 def2 .... As a replacement parameter def1 def2 ..., you can specify any appropriate data object that is visible at this position except for components of [Boxed Components|http://help.sap.com/abapdocu_70/en/ABENBOXED_COMPONENT_GLOSRY.htm].

So in your example we don't have a boxed component, then why do we get this error message? The only way that I can interpret this is that with visible at this position refers to the DEFAULT keyword and not the method and the actual parameter defaulting somehow is implemented as a static method of the class (kind of bootstrapping). Seems far fetched, but otherwise the message makes absolutely no sense. So I'm wondering if this message is just a glitch showing some implementation details (which also would mean the documentation is poor) or if this is a true bug.

The interesting part to me is that once you define your data as class-specific/static (i.e. CLASS-DATA instead of CLASS) then your example doesn't give any syntax error (obviously this defeats the purpose though).

Anyhow, as a general comment I'd like to say that your second coding posting seems anyhow more reasonable. I'd actually shorten the coding by first creating the object and then overriding the attributes if required. Less coding and performance should be the same...

Cheers, harald

Clemenss
Active Contributor
0 Kudos

Hi Jacques,

I don't know where this local class is implemented. You may try

create_copy
        IMPORTING iv_start TYPE date DEFAULT me->mv_start
                  iv_stop TYPE date DEFAULT me->mv_stop
        RETURNING VALUE(ro_range) TYPE REF TO lcl_range.

In the constuctor yo have

super->constructor( ).

But the class lcl_range DEFINITION is not INHERITED FROM an other class. What do I miss here?

Regards,

Clemens

Former Member
0 Kudos

Hi Clemens,

I had tried quite a few syntax variations, including the one that you had given (using <i>me-></i> as prefix), but they either give syntax errors (like in your example) or they don't change the effect that the error message is coming.

As far as the constructor is concerned I'd say the super->constructor() call is simply not required. However, it is my understanding that even without defining a super class, each class automatically is derived from the generic object class as explained in the [ABAP help|http://help.sap.com/saphelp_erp60_sp/helpdata/en/dd/4049c40f4611d3b9380000e8353423/frameset.htm]:

The root node of all inheritance trees in ABAP Objects is the predefined empty class OBJECT. This is the most generalized class possible, since it contains neither attributes nor methods. When you define a new class, you do not have to specify it explicitly as the superclass - the relationship is always implicitly defined.

Interesting though, that I don't see an OBJECT class in the class builder (unlike for example the java.lang.Object class in Java, which actually passes some functionality down). So unless I'm missing something this seems more like an implementation concept/feature that's not visible to the developer.

Cheers, harald