Application Development and Automation 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: 
Read only

better use substring or subfield access?

Sandra_Rossi
Active Contributor
4,176

Hello,

There are recent discussions in the forum that the function substring(...) should always be preferred over the canonical text+off(len) construct ("subfield access"), for instance in that discussion "[you shouldn't] use old-fashioned constructs".

Example of a demo code which implements equivalent substring and text+off(len) constructs:

DATA sub TYPE string.
DATA(text) = `Hello world`.

sub = substring( val = text off = 6 len = 5 ). " new way since 7.02
ASSERT sub = 'world'.

sub = text+6(5). " subfield access, exists for decades
ASSERT sub = 'world'.

I'm really doubtful about this systematic preference, for instance, I prefer a subfield access over substring when the variable is of type C with a fixed length, to avoid the short dump STRING_LENGTH_TOO_LARGE:

DATA sub TYPE string.
DATA(text) = CONV scarr-carrname( 'Air France' )."scarr-carrname=type C length 20

TRY.
    sub = substring( val = text off = 5 len = 10 ).
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx).
ENDTRY.
ASSERT lx IS BOUND.
ASSERT sub = ''.

sub = text+5(10).
ASSERT sub = 'rance'.

For now, I can't say I have a preference between those two, both of them have advantages and drawbacks.

What do you think?

Thanks a lot.

Sandra

@ matthew.billingham

1 ACCEPTED SOLUTION
Read only

Sandra_Rossi
Active Contributor
0 Likes
3,608

In this answer, I will compile the drawbacks and advantages given by the community:

                                           SUBSTRING( VAL = TEXT     TEXT+OFF(LEN)
                                           OFF = OFF LEN = LEN )
----------------------------------------   ---------------------     -------------
1. cx_sy_range_out_of_bounds if                    Yes                    Yes
   off + len > variable size
----------------------------------------   ---------------------     -------------
2. cx_sy_range_out_of_bounds if TEXT is            Yes                    No
   type string & off + len > STRLEN( TEXT )
----------------------------------------   ---------------------     -------------
3. Brevity                                         No                     Yes
----------------------------------------   ---------------------     -------------
4. Compiler check of static form                   No                     Yes
----------------------------------------   ---------------------     -------------
5. Meaningful                                      Yes                    No
----------------------------------------   ---------------------     -------------

Examples for each case:

1. Exception out of bounds (C/D/T/STRING variables)

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
DATA len TYPE i.

TRY.
    sub = substring( val = text off = 5 len = 10 ).
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx1).
ENDTRY.
ASSERT lx1 IS BOUND. " exception

TRY.
    sub = text+5(len).
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx2).
ENDTRY.
ASSERT lx2 IS BOUND. " exception

2. Exception with C/N/D/T variables if extracting trailing spaces

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
text = 'Hello'.

TRY.
    sub = substring( val = text off = 0 len = 10 ). " error
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx).
ENDTRY.
ASSERT lx IS BOUND. " exception because text is considered 5 characters long

sub = text+0(10). " no exception

4. Compiler check of static form

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
sub = substring( val = text off = 5 len = 10 ). " no syntax error
sub = text+5(10). " syntax error

In this answer, I will compile the drawbacks and advantages given by the community:

                                           SUBSTRING( VAL = TEXT     TEXT+OFF(LEN)
                                           OFF = OFF LEN = LEN )
----------------------------------------   ---------------------     -------------
1. cx_sy_range_out_of_bounds if                    Yes                    Yes
   off + len > variable size
----------------------------------------   ---------------------     -------------
2. cx_sy_range_out_of_bounds if TEXT is            Yes                    No
   type string & off + len > STRLEN( TEXT )
----------------------------------------   ---------------------     -------------
3. Brevity                                         No                     Yes
----------------------------------------   ---------------------     -------------
4. Compiler check of static form                   No                     Yes
----------------------------------------   ---------------------     -------------
5. Meaningful                                      Yes                    No
----------------------------------------   ---------------------     -------------

Examples for each case:

1. Exception out of bounds (C/D/T/STRING variables)

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
DATA len TYPE i.

TRY.
    sub = substring( val = text off = 5 len = 10 ).
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx1).
ENDTRY.
ASSERT lx1 IS BOUND. " exception

TRY.
    sub = text+5(len).
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx2).
ENDTRY.
ASSERT lx2 IS BOUND. " exception

2. Exception with C/N/D/T variables if extracting trailing spaces

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
text = 'Hello'.

TRY.
    sub = substring( val = text off = 0 len = 10 ). " error
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx).
ENDTRY.
ASSERT lx IS BOUND. " exception because text is considered 5 characters long

sub = text+0(10). " no exception

4. Compiler check of static form

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
sub = substring( val = text off = 5 len = 10 ). " no syntax error
sub = text+5(10). " syntax error
9 REPLIES 9
Read only

former_member184158
Active Contributor
3,608

Hello Sandra Rossi,

thank you for this question I use both but both you can get dump but when!

you will get also dump when you use subfield. Have you tried this statement sub =text+5(16)?

DATA(text) = CONV scarr-carrname( 'Air France' ). " S_CARRNAME = CHAR20

sub =text+5(16).  "--> Dump more than 20 chars

"16 + 5 = 21 then in this case you will get also dump 
"Just try it. 

Invalid subfield access: Offset plus length too long

Best regards

Ebrahim

Read only

Sandra_Rossi
Active Contributor
3,608

Ebrahim Hatem of course 🙂 Both have advantages, drawbacks. I find it more tricky to use substring on C-fixed-length variables because they can have an unknown number of trailing spaces.

(note: text+5(16) -> exception cx_sy_range_out_of_bounds)

Read only

matt
Active Contributor
3,608

I prefer substring simply because it has more meaning than +()

Read only

DoanManhQuynh
Active Contributor
3,608

I prefer subfield access because it short :).

I think in the view of functional programming, its clearer when using substring( ) thats why it is preferred than subfield. with substring( ) you also can catch the exception, although I feel its annoying to TRY...CATCH just for simple statement like that...in subfield, if off and len is explicit then the complier always check it against total len (at least in my 7.4) -> coudnt be dump as Ebrahim Hatem said.

Read only

matt
Active Contributor
3,608

"because it's short"

I'm not 100% convinced that is the right motivation. Do you use not entirely clear variable names for the same reason?

The motivation should be whether substring/subfield is clearer to the programmer working on the program in a few years. Who's a homicidal maniac with anger management issues and knows where you live. 😄

"it's annoying"

I generally check the bounds before using substring, so that I don't get a failure - nonetheless I think it is good programming practice to surround with try/catch. Why should writing robust code be annoying?

On a scale of 1 to 10, with 10 being best 1 being worst, I'd rate using subfield as an 8 and substring as 10. It's marginally better. If ABAP was invented now, I'd bet you wouldn't have subfield access.

Read only

Sandra_Rossi
Active Contributor
0 Likes
3,608

Quynh Doan Manh With subfield, the compiler doesn't always check the values in any dynamic construct (text of type String, variable for offset and length), it's only when everything is constant (and text of type C) that the compiler does the check. And it doesn't with substring. So it's another advantage of using subfield access with fields of type C.

Matthew Billingham I think "it's short" is a valid motivation in any programming language. Provided it's comprehensible. Maybe text+off(len) is not comprehensible to novices, but that's the same thing for many constructs (especially constructor expressions nowadays).

Read only

former_member184158
Active Contributor
0 Likes
3,608

Hello Sandra Rossi,

your question is like which better to use for reading an internal table

  DATA(ls_str) = lt_tab[  lines( lt_tab ) ]. " dump when LT_TAB empty
"   This row is not contained in the table.	 
     read table lt_tab into data(ls_str) index  lines( lt_tab ).    
  " hier Sy-subrc = 4... when LT_TAB empty                        

Best regards

Read only

Sandra_Rossi
Active Contributor
3,608

Ebrahim Hatem Yes. A table expression is easier to handle than substring though, because it's possible to wrap it inside VALUE #( ... OPTIONAL ).

Read only

Sandra_Rossi
Active Contributor
0 Likes
3,609

In this answer, I will compile the drawbacks and advantages given by the community:

                                           SUBSTRING( VAL = TEXT     TEXT+OFF(LEN)
                                           OFF = OFF LEN = LEN )
----------------------------------------   ---------------------     -------------
1. cx_sy_range_out_of_bounds if                    Yes                    Yes
   off + len > variable size
----------------------------------------   ---------------------     -------------
2. cx_sy_range_out_of_bounds if TEXT is            Yes                    No
   type string & off + len > STRLEN( TEXT )
----------------------------------------   ---------------------     -------------
3. Brevity                                         No                     Yes
----------------------------------------   ---------------------     -------------
4. Compiler check of static form                   No                     Yes
----------------------------------------   ---------------------     -------------
5. Meaningful                                      Yes                    No
----------------------------------------   ---------------------     -------------

Examples for each case:

1. Exception out of bounds (C/D/T/STRING variables)

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
DATA len TYPE i.

TRY.
    sub = substring( val = text off = 5 len = 10 ).
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx1).
ENDTRY.
ASSERT lx1 IS BOUND. " exception

TRY.
    sub = text+5(len).
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx2).
ENDTRY.
ASSERT lx2 IS BOUND. " exception

2. Exception with C/N/D/T variables if extracting trailing spaces

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
text = 'Hello'.

TRY.
    sub = substring( val = text off = 0 len = 10 ). " error
  CATCH cx_sy_range_out_of_bounds INTO DATA(lx).
ENDTRY.
ASSERT lx IS BOUND. " exception because text is considered 5 characters long

sub = text+0(10). " no exception

4. Compiler check of static form

DATA sub TYPE string.
DATA text TYPE c LENGTH 10.
sub = substring( val = text off = 5 len = 10 ). " no syntax error
sub = text+5(10). " syntax error