2019 May 08 10:43 AM
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
2019 May 13 8:55 AM
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 exception4. 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
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
2019 May 08 12:29 PM
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 longBest regards
Ebrahim
2019 May 08 1:26 PM
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)
2019 May 09 6:26 AM
I prefer substring simply because it has more meaning than +()
2019 May 10 1:54 AM
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.
2019 May 10 6:39 AM
"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.
2019 May 10 7:53 AM
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).
2019 May 13 8:20 AM
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
2019 May 13 8:28 AM
Ebrahim Hatem Yes. A table expression is easier to handle than substring though, because it's possible to wrap it inside VALUE #( ... OPTIONAL ).
2019 May 13 8:55 AM
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 exception4. 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
| User | Count |
|---|---|
| 3 | |
| 2 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |