Statement not accessible - abap

there is error in line 49 where I wrote CALL METHOD lclref->lcm . how can i solve it?
REPORT ZPRACTICE_TILL_NOW.
include zlc.
include zinc.
START-OF-SELECTION.
create OBJECT lclref.
CALL METHOD lclref->lcm .
first include:
class zlcl DEFINITION.
PUBLIC SECTION.
METHODS: lcm.
ENDCLASS.
CLASS zlcl IMPLEMENTATION.
method lcm.
new-LINE.
WRITE: 'method called '.
ENDMETHOD.
ENDCLASS.
second include:
*&---------------------------------------------------------------------*
*& Include ZINC
*&---------------------------------------------------------------------*
data lclref TYPE REF TO zlcl.

The error 'Statement not accessible' is because lclref is an object .
To call a method of an object which is referenced to a class ( in this case object -> lclref and class ->zlcl ).
you can directly specify the object and the method .
Hence the corrected code would be : lclref->lcm.
Have fun.

*&---------------------------------------------------------------------*
*& Include ZINC
*&---------------------------------------------------------------------*
data lclref TYPE REF TO zlcl.
Are you sure first INCLUDE is zinc
class zlcl DEFINITION.
PUBLIC SECTION.
METHODS: lcm.
ENDCLASS.
CLASS zlcl IMPLEMENTATION.
method lcm.
new-LINE.
WRITE: 'method called '.
ENDMETHOD.
ENDCLASS.
When I tried with your code I did not getting any error. Please check your INCLUDE which one is the first?
I do not know your SAP version If supports you can use inline declaration. You can see the below example. No need to an extra data declarations
DATA(lo_lcl) = new zlcl( ).
lo_lcl->lcm( ).

Related

SystemVerilog interface - Passing parameters after module declaration

Given the following module declaration:
module ( myinterface.mymodport mybus, ... );
And assuming that myinterface has parameters, how do I specify them?
The interface instantiation happens only in the testbench, but now I want to synthesize the DUT, so the TB disappears.
This is an oversight in the SystemVerilog LRM. There's no syntax to specify a required set of parameters for an interface in a module header.
You might check your synthesis tool to see if they provide any way of specifying parameter overrides for the top-level synthesis instance.
You specify the parameter when you instantiate the interface; you do not specify it in the port list of the module. Given
interface myinterface #(parameter DATA_SIZE = 0);
...
All you need is
module mymodule (myinterface.mymodport mybus);
...
because somewhere else you have
myinterface #(.DATA_SIZE(64)) i();
interface myinterface #(parameter DATA_SIZE = 0);
logic [DATA_SIZE-1:0] AWID;
logic [31:0] AWADDR;
modport mymodport (input AWID, AWADDR);
endinterface
module mymodule (myinterface.mymodport mybus);
initial
$display("mymodule");
endmodule
module top;
myinterface #(.DATA_SIZE(64)) i();
mymodule m (.mybus(i));
endmodule
https://www.edaplayground.com/x/528x

Using public and private methods inside their class in Perl 6

If I have a public method, I can call it inside its class using both $.name and self.name:
class TEST {
has Int $.a;
method b($x) {
return $!a * $x;
}
method c($y) {
return self.b($y) * 3; # or $.b($y)
}
}
my $m = TEST.new(a => 10);
say $m.c(2); # 60
But if I make b a private method, I only can call it with self!b, not $!b, otherwise I get the following error message:
Attribute $!b not declared in class TEST
What's behind this rule? What are the rules of calling a method inside its own class?
An attribute can always be referred to as $!foo in a class. If you do that, than the code will be generated to directly access the attribute itself, and any classes subclassing your class will not be able to change this behaviour.
If you use has $.foo in the declaration of a class, it means that a public accessor (and if you add is rw it can also function as a mutator).
When you use $.foo in your code otherwise, it is exactly the same as $( self.foo ). This means that it will call the method foo on self, and itemize the return value (make it a single "thing" if it wasn't yet). This will go wrong if you defined your attribute with $!foo and you did not supply a method foo yourself.
This goes even further: $.bar really means self.bar: you only need to have a method existing by the name bar, which may not be related to any attribute at all.
If you define a private method !baz, the ! just indicates the privacy of the method, which means you need to call it indeed as self!baz. There is no short syntax for it.
Personally I dislike the fact that you can say $.zippo even if zippo is not an attribute. But I'm afraid that ship has sailed. But this behaviour is now causing you confusion :-(
So what's behind the rule for not having a short syntax for calling a private method? Not sure, I guess really that $!foo was already taken to mean direct access to the attribute, and provide you with a compile time error if the attribute doesn't exist.
Hope this answers your question!

OOABAP: Calling a class method with a class object

In the program e1 is class event and c1 a class method. I tried calling class event using invocation for class methods c1=>t1 and invocation for object methods c1->t1 and both are successful. why?
As we know class methods are always called by c1=>t1.
REPORT my_event7.
CLASS c1 DEFINITION.
PUBLIC SECTION.
CLASS-EVENTS: e1.
METHODS: m1 FOR EVENT e1 OF c1.
CLASS-METHODS : t1.
ENDCLASS. "c1 DEFINITION
CLASS c1 IMPLEMENTATION.
METHOD : t1.
WRITE:/5 'C1->T1'.
RAISE EVENT e1.
ENDMETHOD.
METHOD : m1.
WRITE:/5 ' C1->M1'.
ENDMETHOD. ":
ENDCLASS. "c1 IMPLEMENTATION
CLASS c2 DEFINITION.
PUBLIC SECTION.
METHODS: m2 FOR EVENT e1 OF c1.
ENDCLASS. "c2 DEFINITION
CLASS c2 IMPLEMENTATION.
METHOD : m2.
WRITE:/5 ' C2->M2'.
ENDMETHOD.
ENDCLASS. "c2 IMPLEMENTATION
START-OF-SELECTION.
DATA: oref1 TYPE REF TO c1.
DATA: oref2 TYPE REF TO c2.
CREATE OBJECT: oref1 .
CREATE OBJECT: oref2 .
SET HANDLER oref1->m1 oref2->m2.
CALL METHOD c1=>t1.
CALL METHOD oref1->t1.
You may call it syntactical sugar.
Class methods can be called without any instance with <classname>=>method.
But you can also call the class method via the instance of the class. And then you can use the normal method call with ->. But in background the class method is called.

Explicit inheritance from Any in Kotlin - Can and How is it done?

The Kotlin documentation says that
All classes in Kotlin have a common superclass Any, that is a default super for a class with no supertypes declared
If I try and explicitly inherit from Any:
class MyClass : Any {
}
The compiler gives an error:
Kotlin: This type has a constructor, and thus must be initialized here
I haven't been able to find the documentation for the Any class. Is it possible to explicitly inherit from Any, and if so, what do you pass it?
You have to call the constructor explicitly:
class MyClass : Any()
THe constructor of Any has no parameters, thus to call it you simply provide the empty parentheses
In case we are extending a class,we need to add brackets(for implicit constructor)
class MyClass : Any()
This is similar to calling
class MyClass extends Any
{
MyClass()
{
super();
}
}
But if we are implementing an interface(interface do not have constructors),syntax should be the following
class MyClass : BaseInterface
In case when you have secondary constructor (key word constructor) you can use the next syntax
class MyClass : Any {
constructor() : super()
}
If the class has no primary constructor, then each secondary constructor has to initialize the base type using the super keyword, or to delegate to another constructor which does that.
Read more here - https://kotlinlang.org/docs/reference/classes.html
P.S. your problem could be solved easily using Android Studio feature - Project quick fix (show intention actions and quick fixes) Win - Alt + Enter, Mac - Option + Enter

Why does the second CREATE OBJECT generate a short dump?

I have got a following case.
An include with a local interface definition
*&---------------------------------------------------------------------*
*& Include ZZZ_INCL_INTERFACE
*&---------------------------------------------------------------------*
INTERFACE lif_test.
METHODS:
test.
ENDINTERFACE. "lif_test
A report which uses this include and defines a class implementing this interface.
*&---------------------------------------------------------------------*
*& Report ZZZ_IMPL_A
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zzz_impl_a.
INCLUDE zzz_incl_interface.
*----------------------------------------------------------------------*
* CLASS lcl_test_a DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_a DEFINITION FINAL.
PUBLIC SECTION.
INTERFACES:
lif_test.
ENDCLASS. "lcl_test_a DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_test_a IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_a IMPLEMENTATION.
METHOD lif_test~test.
ENDMETHOD. "lif_test~test
ENDCLASS. "lcl_test_a IMPLEMENTATION
And a second report which also uses this include and defines a new class also implementing the same interface defined in the include.
*&---------------------------------------------------------------------*
*& Report ZZZ_IMPL_B
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zzz_impl_b.
INCLUDE zzz_incl_interface.
*----------------------------------------------------------------------*
* CLASS lcl_test_b DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_b DEFINITION FINAL.
PUBLIC SECTION.
INTERFACES:
lif_test.
ENDCLASS. "lcl_test_b DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_test_b IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_b IMPLEMENTATION.
METHOD lif_test~test.
ENDMETHOD. "lif_test~test
ENDCLASS. "lcl_test_b IMPLEMENTATION
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA:
l_rif_test TYPE REF TO lif_test.
CREATE OBJECT l_rif_test TYPE ('\PROGRAM=ZZZ_IMPL_B\CLASS=LCL_TEST_B').
CREATE OBJECT l_rif_test TYPE ('\PROGRAM=ZZZ_IMPL_A\CLASS=LCL_TEST_A').
ENDMETHOD.
ENDCLASS.
END-OF-SELECTION.
lcl_main=>main( ).
The line CREATE OBJECT l_rif_test TYPE ('\PROGRAM=ZZZ_IMPL_A\CLASS=LCL_TEST_A') generates a short dump saying that the dynamically created object is not an implementation of lif_test. Could one explain why it is like that? It looks like a great hole in the language definition. To stop any discussion at the very beginning: No I cannot use dictionary definition of the interface.
EDIT: More descriptive short dump is obtained when trying to cast the instance of the object created by the second CREATE OBJECT.
DATA:
l_rcl_object TYPE REF TO object.
*...
CREATE OBJECT l_rcl_object TYPE ('\PROGRAM=ZZZ_IMPL_A\CLASS=LCL_TEST_A').
l_rif_test ?= l_rcl_object.
The short dump has it that
The content of the source variable does not fit in the target variable.
Source type: "\PROGRAM=ZZZ_IMPL_A\CLASS=LCL_TEST_A"
Target type: "\PROGRAM=ZZZ_IMPL_B\INTERFACE=LIF_TEST"
It looks like when I include a local definition of an interface in two places they become a two separate definitions, one of program ZZZ_IMPL_B and the second of ZZZ_IMPL_A.
The reason for this behavior is that INCLUDE does just that - it includes the contents of the include at the point of the INCLUDE statement, which is slightly better than copy&paste from a developer's point of view, but the same thing as far as the system is concerned. You get two interface definitions in distinct programs that are equal, but not identical. One solution might be to generate a report, a subroutine pool, a function pool or a module pool that contains the interface. These program types generate their own loads, so you'll get an interface \PROGRAM=ZZZ_MY_SUBROUTINE_POOL\INTERFACE=LIF_TEST that you can then use from your other programs. Note that you'll still have to write this subroutine pool to the repository, just keeping it locally won't help.
(Other than that, why exactly isn't generating global interface and classes an option?)
You should put your class A and B definitions and implementations inside separate includes, and include those along with the interface inside the report containing your main class. Like this:
report zzz_impl.
include zzz_incl_interface.
include zzz_incl_a.
include zzz_incl_b.
class lcl_main definition final create private.
public section.
class-methods:
main.
endclass.
class lcl_main implementation.
method main.
data l_rif_test type ref to lif_test.
create object l_rif_test type lcl_test_b.
create object l_rif_test type lcl_test_a.
endmethod.
endclass.
end-of-selection.
lcl_main=>main( ).
The reason for the shortdump, is because you're trying to use a variable of the type \PROGRAM=ZZZ_IMPL_B\INTERFACE=LIF_TEST to refer to an object which implements \PROGRAM=ZZZ_IMPL_A\INTERFACE=LIF_TEST.
Edit: I'm not entirely sure what you mean with your comment, but maybe generating the entire report is possible for your use case? For example:
report zzz_impl_gen.
data source_interface type standard table of char255.
append `interface lif_test.` to source_interface.
append ` methods:` to source_interface.
append ` test.` to source_interface.
append `endinterface.` to source_interface.
data source_class_a type standard table of char255.
append `class lcl_test_a definition final.` to source_class_a.
append ` public section.` to source_class_a.
append ` interfaces:` to source_class_a.
append ` lif_test.` to source_class_a.
append `endclass.` to source_class_a.
append `class lcl_test_a implementation.` to source_class_a.
append ` method lif_test~test.` to source_class_a.
append ` endmethod.` to source_class_a.
append `endclass.` to source_class_a.
data source_class_b type standard table of char255.
append `class lcl_test_b definition final.` to source_class_b.
append ` public section.` to source_class_b.
append ` interfaces:` to source_class_b.
append ` lif_test.` to source_class_b.
append `endclass.` to source_class_b.
append `class lcl_test_b implementation.` to source_class_b.
append ` method lif_test~test.` to source_class_b.
append ` endmethod.` to source_class_b.
append `endclass.` to source_class_b.
data source_main type standard table of char255.
append `class lcl_main definition final create private.` to source_main.
append ` public section.` to source_main.
append ` class-methods:` to source_main.
append ` main.` to source_main.
append `endclass.` to source_main.
append `class lcl_main implementation.` to source_main.
append ` method main.` to source_main.
append ` data l_rif_test type ref to lif_test.` to source_main.
append ` create object l_rif_test type lcl_test_b.` to source_main.
append ` create object l_rif_test type lcl_test_a.` to source_main.
append ` write: / 'Hello, World!'.` to source_main. " Just to test if it works
append ` endmethod.` to source_main.
append `endclass.` to source_main.
data source_form type standard table of char255.
append `form main.` to source_form.
append ` lcl_main=>main( ).` to source_form.
append `endform.` to source_form.
data source_all type standard table of char255.
append `program subpool.` to source_all.
append lines of source_interface to source_all.
append lines of source_class_a to source_all.
append lines of source_class_b to source_all.
append lines of source_main to source_all.
append lines of source_form to source_all.
data generated_program type string.
data message type string.
data sid type string.
generate subroutine pool source_all name generated_program message message shortdump-id sid.
perform ('MAIN') in program (generated_program) if found. " Important, subroutine name must be in upper case!