How to Debug Methods from Reference Classes

How to debug methods from Reference Classes?

You want to call the trace method of the instance object.

a$trace("setFields")

This is the implementation that you want for the setFields method.

AB.setFields <- function(...) {
dots <- list(...)
fieldNames <- names(dots)
for(i in seq_along(dots))
{
assign(fieldNames[[i]], dots[[i]], attr(.self, ".xData"))
}
}

a$setFields(name="aaa",var2=factor(1:3))

There's probably some syntactic sugar I've missed to make this prettier, but to get all your fields, you can use

AB.getFields <- function(){
mget(
names(.refClassDef@fieldClasses),
envir = attr(.self, ".xData")
)
}

Looking for Java method capable of identifying which method it is called by

This can be done using a StackWalker (since Java 9). It does not directly
provide a Method but enough information to create one.
Here the basic idea, can be improved (e.g. better Exception(s)):

import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.reflect.Method;

public class MethodFinder {

public static Method method() {
return StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).walk(stream ->
stream
.filter(MethodFinder::notThisClass)
.findFirst()
.map(MethodFinder::frameToMethod))
.orElseThrow();
}

private static boolean notThisClass(StackFrame frame) {
return frame.getDeclaringClass() != MethodFinder.class;
}

private static Method frameToMethod(StackFrame frame) {
var cl = frame.getDeclaringClass();
try {
return cl.getDeclaredMethod(frame.getMethodName(), frame.getMethodType().parameterArray());
} catch (NoSuchMethodException | SecurityException ex) {
throw new RuntimeException(ex);
}
}
}

To be used like Method myself = MethodFinder.method().

Debugging: How to 'sneak' into other class object declared in class

Just be clicking "step in" F5 default key in eclipse debugger. It will send you in the desired setter if you have the sources attached.

String tempString = jsonObject1.getString("some");
modelClass.setString(tempString);

Use these style: call your methods one per line and debugging will be easier. Debugging is a great part of programming. I don't know why the new technologies does not focus so much on easy debugging. For example Java 8 is very difficult for debugging - only with an appropriate code styling you can debug it.

Can I set breakpoints to all methods in a class at once in Visual Studio?

There is an addon-less method described here:
How to set a breakpoint on a C++ class in the Visual Studio Debugger

In short, you can bring up the "New Breakpoint" dialog by pressing Ctrl+K, B and type in ClassName::* to the function field. In Visual Studio 2017 you need to include the namespace in the field, as in NamespaceName::ClassName::*.
You can then disable some of them in the breakpoints window.

Is there any way to set breakpoints on all methods of a class?

I have discovered workaround :


1. I have set "Toggle Brakepoint" hotkey to Alt+Numpad 0.

2. After that you can click on first method

3. Use "Toggle Brakepoint"

4. Alt+Down - goto Next Method. ( Alt+Up - goto Previous Method. )

5. Repeat 3 step.

How to (if possible) get the reference of an in-memory object (class instance)?

I hope I understand your question correctly, because I am not sure what you mean with "for the purpose of debugging", but here goes:

You can access the variables of another program that are loaded in the memory of the same session (I am pretty sure it does not need to be in the call stack) using:

ASSIGN ('(PROGRAM)VARIABLE') TO LV_LOCAL.

With reference variables, it becomes a bit more tricky, but here is an example that will help to demonstrate.

Here is our calling program that contains a reference variable LR_TEST which we want to access somewhere else. For the purpose of the demonstration, I make reference to a locally defined class (because that's what I gather from your question).

REPORT  ZCALLER.

class lcl_test definition.
public section.
data: myval type i.

methods: my_meth exporting e_val type i.
endclass.

data: lr_test type ref to lcl_test.

CREATE OBJECT lr_test.

lr_test->MYVAL = 22.

perform call_me(zcallee).

class lcl_test implementation.
method my_meth.
* Export the attribute myval as param e_val.
e_val = myval.
endmethod.
endclass.

Here is the program in which we want to access a variable from the above program.

REPORT  ZCALLEE.

form call_me.

field-symbols: <ref>.
data: ld_test type ref to object.
data: lv_val type i.

* Exhibit A: Gettinf a reference to a 'foreign' object instance
assign ('(ZCALLER)LR_TEST') to <ref>.
* <ref> now contains a reference to the class instance from the program
* ZCALLER (not very useful, except for passing around maybe)

* Exhibit B: Getting a public attribute from a 'foreign' class instance
assign ('(ZCALLER)LR_TEST->MYVAL') to <ref>.
* <ref> now contains the value of the attribute MYVAL

* Exhibit C: Getting a reference to an instance and calling a method
assign ('(ZCALLER)LR_TEST') to <ref>. "Again the class reference
if sy-subrc = 0. "Rule: Always check sy-subrc after assign before
"accessing a field symbol! (but you know that)
ld_test = <ref>. "Now we have a concrete handle
* Now we make a dynamic method call using our instance handle
CALL METHOD ld_test->('MY_METH')
IMPORTING
e_val = lv_val.
endif.
endform.


Related Topics



Leave a reply



Submit