Extend extended type - oop

I want to extend a Fortran type that already extends a type. I know that when I have an extended type I can write
type o1
...
type, extends(o1) :: o2
...
type(Object1) :: o1
allocate(o2::o1)
How does this work when I have a third type that extends o2? Is this possible?

Yes. Restating the code and renaming for clarity:
type :: t1 ! The top level parent type.
integer :: c1 ! A component in the parent type.
end type t1
type, extends(t1) :: t2 ! An extension of t1.
integer :: c2
end type t2
type, extends(t2) :: t3 ! A further extension of t2.
integer :: c3
end type t3
! Declare an object of declared type t1.
class(t1), allocatable :: object
! Allocate that object, giving it a dynamic type of t3.
allocate(t3 :: object)
object%c1 = 1 ! c1 is a component of the declared type.
! Use select type or a type bound procedure to access c2 and c3.

Related

Prevent CL_SALV_TABLE from removing leading zeros?

Please take a look on this following piece of code in which I put zeros in Test2 as value and two zeros in Test3 as value.
i used set_leading_zero but still leading zeros are removed.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
TYPES: BEGIN OF l_tys_test,
name TYPE string,
value TYPE i,
END OF l_tys_test,
l_tyt_test TYPE STANDARD TABLE OF l_tys_test WITH EMPTY KEY.
DATA(lt_test) = VALUE l_tyt_test(
( name = `Test1` value = 1 )
( name = `Test2` value = 02 )
( name = `Test3` value = 003 )
).
cl_salv_table=>factory(
IMPORTING
r_salv_table = DATA(lo_salv_table)
CHANGING
t_table = lt_test
).
lo_salv_table->get_columns( )->get_column( 'VALUE' )->set_leading_zero( abap_true ).
lo_salv_table->display( ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
Agree with Jozsef and Sandra, there is no way you can do it with integer data type.
The only way how to implement this by means of ALV grid is to redeclare you VALUE field as numchar
TYPES: BEGIN OF
...
value TYPE n LENGTH 10,
...
END OF.
and utilize EDIT_MASK function, which is available both for WRITE statement and for ALV grid as well.
Put this instead of set_leading_zero( ) call in your method
lo_salv_table->get_columns( )->get_column( 'VALUE' )->set_edit_mask( '___________' ).
LENGTH specification in type definition is the number of leading zeroes to put.
You can use set_zero method to false.
DATA(lo_column) = lo_alv->get_columns( )->get_column( 'PERNR' ). lo_column->set_long_text( 'Staff No' ). lo_column->set_zero( abap_false ).

How to create a internal table based on object attribute?

I am trying to create sorted table based on instances.
Here below my coding :
CLASS my_fancy_pony DEFINITION.
PUBLIC SECTION.
DATA mv_nice_key TYPE i.
ENDCLASS.
CLASS my_fancy_pony IMPLEMENTATION.
ENDCLASS.
DATA lt_my_fancy_ponys TYPE SORTED TABLE OF REF TO my_fancy_pony WITH UNIQUE KEY mv_nice_key.
DATA lt_my_fancy_ponys TYPE SORTED TABLE OF REF TO my_fancy_pony WITH UNIQUE KEY table_line->mv_nice_key.
This is not passing through the syntax check.
Could you tell how I can achieve that?
You can't use classes directly as structures.
However, you can construct a map that does what you need:
TYPES:
BEGIN OF map_entry,
mv_nice_key TYPE i,
ref_to_object TYPE REF TO my_fancy_pony,
END OF map_entry.
TYPES map_type TYPE SORTED TABLE OF map_entry WITH UNIQUE KEY mv_nice_key.
DATA(lt_my_fancy_pony_map) = VALUE map_type(
FOR each IN lt_my_fancy_ponys
( mv_nice_key = each->mv_nice_key
ref_to_object = each ) ).
The map can number any of the class's attributes that you need:
TYPES:
BEGIN OF map_entry,
mv_nice_key TYPE i,
some_other_att TYPE i,
" ...
ref_to_object TYPE REF TO my_fancy_pony,
END OF map_entry.
TYPES map_type TYPE SORTED TABLE OF map_entry WITH NON-UNIQUE KEY table_line.
DATA(lt_my_fancy_pony_map) = VALUE map_type(
FOR each IN lt_my_fancy_ponys
( mv_nice_key = each->mv_nice_key
some_other_att = each->some_other_att
" ...
ref_to_object = each ) ).

Conversion exception while working with constructor expressions

I'm working on a routine which moves the lines of a string table (in this case fui_elements) into a structure of unknown type (fcwa_struct).
DATA(li_temp) = ... "fill assignment table here
LOOP AT fui_elements ASSIGNING FIELD-SYMBOL(<lfs_element>).
ASSIGN COMPONENT li_temp[ sy-tabix ] OF STRUCTURE fcwa_struct
TO FIELD-SYMBOL(<lfs_field>).
IF sy-subrc <> 0.
"somethings wrong with the fui_elements data
ENDIF.
<lfs_field> = <lfs_element>.
ENDLOOP.
If the table i_field_customizing (STANDARD TABLE OF string) is not initial, I want to use its values.
Otherwise I want to generate an integer table (so that the loop runs equally often regardless of the table's values). Here lw_max is the amount of fields the imported structure has:
DATA(li_temp) = COND #( WHEN i_field_customizing[] IS INITIAL
THEN VALUE t_integer_tt( FOR X = 1
THEN X + 1
WHILE X <= lw_max
( X ) )
ELSE i_field_customizing ).
But when I run the report with i_field_customizing like that:
DATA(i_field_customizing) = VALUE t_string_tt( ( `KUNNR` ) ( `NAME1` ) ).
I get this exception on the line where I try to construct li_temp:
CX_SY_CONVERSION_NO_NUMBER (KUNNR cannot be interpreted as a number)
My current guess is that COND gets its type statically. Does anybody know how I can get around this?
What you are trying to achieve will not be possible because the type of an inline definition of a variable using COND is decided at compilation time and not at runtime.
Please see my question here. The type that will be taken is always the type of the variable that stands directly after THEN. You can decide what type will be chosen at compilation time by fiddling with negating the condition and switching places of variables after THEN at ELSE but it will be always either or and from what I understand you want to be able to do it dynamically so your ASSIGN COMPONENT statement works as expected with integers.
Even by specifically casting the variable after ELSE one gets the same short dump as you do.
DATA(li_temp) = COND #( WHEN i_field_customizing IS INITIAL
THEN VALUE t_integer_tt( ( 1 ) ( 2 ) )
ELSE CAST t_string_tt( REF #( i_field_customizing ) )->* ).
Alternatively you could cast to REF TO DATA but then you have to dereference it to a field symbol of type STANDARD TABLE.
REPORT zzy.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
TYPES:
t_integer_tt TYPE STANDARD TABLE OF i WITH EMPTY KEY,
t_string_tt TYPE STANDARD TABLE OF string WITH EMPTY KEY.
FIELD-SYMBOLS:
<fs_table> TYPE STANDARD TABLE.
DATA: BEGIN OF l_str,
kunnr TYPE kunnr,
name1 TYPE name1,
END OF l_str.
* DATA(i_field_customizing) = VALUE t_string_tt( ( `KUNNR` ) ( `NAME1` ) ).
DATA(i_field_customizing) = VALUE t_string_tt( ).
DATA(li_temp) = COND #( WHEN i_field_customizing IS INITIAL
THEN CAST data( NEW t_integer_tt( ( 1 ) ( 2 ) ) )
ELSE CAST data( REF #( i_field_customizing ) ) ).
ASSIGN li_temp->* TO <fs_table>.
LOOP AT <fs_table> ASSIGNING FIELD-SYMBOL(<fs_temp>).
ASSIGN COMPONENT <fs_temp> OF STRUCTURE l_str TO FIELD-SYMBOL(<fs_field>).
ENDLOOP.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).

Coq - Passing parameters to a record

I'm having trouble in comparing elements of sets belonging to two distinct
instances of the same record type. Consider the following record.
Record ToyRec := {
X:Set;
Labels:Set;
r:X->Labels
}
Say that two objects T1 and T2 of type ToyRec form a good pair if
for every element in T1.(X) there exists an element in T2.(X) with the
same label.
Definition GoodPair(T1 T2:ToyRec):Prop :=
forall x1:T1.(X), exists x2:T2.(X), T1.(r) x1 = T2.(r) x2.
The problem is that I get an error saying that T1.(r) x1 is of type X1.(Labels),
and T2.(r) x2 is of type X2.(Labels).
I understand the problem, and I imagine it could be solved if I could somehow
declare the set Labels outside the record, and then pass it as a parameter.
Is there a way to do this in Coq? Or what would be the most elegant way of
defining the records I want and the property GoodPair?
The closest thing I got from your code his the following:
Record ToyRec {Labels : Set} := {
X:Set;
r:X->Labels
}.
Definition GoodPair {Labels:Set} (T1 T2 : #ToyRec Labels) : Prop :=
forall x1: X T1, exists x2: X T2, r T1 x1 = r T2 x2.
By having Labels as a dependency for ToyRec you can be sure that both records are using the same type.
PS: I used {Labels : Set} instead of (Labels : Set) to specify that this argument is implicit and should be inferred whenever possible.

Currying and compiler design

This is a homework question:
Explain the transformations the type
of a routine undergoes in partial
parameterization.
So far I understand currying. But I cannot find any resources on how a function like this is implemented by the compiler in memory. Could I be pointed in the right direction, maybe keywords to search for or links to resources or possibly an explanation here of how the compiler generates the type and symbol table among other things thats related to the question.
Thanks.
Currying is the conversion of n argument functions into n unary functions:
Example, if you have a ternary function f :: t1 x t2 x t3 -> t you can represent this function as
f1 :: t1 -> (t2 -> (t3 -> t))
In other words, f1 is a function which takes an argument of type t1 and returns a function of type f2.
f2 :: t2 -> (t3 -> t)
f2 is a function which takes an argument of type t2 and returns a function of type f3.
f3 :: t3 -> t
f3 is a function which takes an argument of type t3 and returns type t.
Example, if f(a,b,c) = a+b*c then:
f3(C) == c1+c2*C where c1 and c2 are constant.
f2(B) == f3(C) where c1 is constant and c2 is replaced with B.
f1(A) == f2(B) where c1 is replaced with A.
In functional languages, functions are first class citizens so its common to have them as return type.
Currying is like fixing a parameter of the function. What you really need to modify is the prototype of the function called.. if you have for example retn_type function(param1, param2) and you currying it on first parameter you set it to a fixed value and you obtain a new function retn_type(param2) that can be called and passed in a different way from the original one.
Actually you can obtain it in a compiler in many ways or hacks but the core of everything to its simplicity is just to redefine a new version that is linked to first one. So when you call retn_type(param2) you execute the same code of first function assuming that parameter1 is specified by curryfication.