On 09/20/2013 01:19 PM, Jochen Theodorou wrote:
that is I think a usecase for some... as I said, getCallerClass(int)
is not really ideal for us either. More ideal in this style would be
for us
public static <T> T findCaller(Predicate<StackFrameInfo> predicate,
Function<StackFrameInfo,T> function)
with the predicate indicating when to stop..
As I understand the Thread.firstCaller() does exactly that.
"findFirstCallerMatchingPredicate". Choosen name abbreviation is maybe
not making the semantic immediately obvious.
though the usage of this is not that nice:
Class getCallerClass(final int nonSkippedFramesDepth) {
return findCaller(new Predicate<StackFrameInfo>() {
int depth = 0;
boolean test(StackFrameInfo info) {
if (haveToSkip(info.getDeclaringClass())) return
false;
depth++;
if (depth>=nonSkippedFramesDepth) return
info.getDeclaringClass();
}
}, StackFrameInfo::getDeclaringClass());
}
But the API is making it possible without walking entire stack or making
N partial walks with lengths 1..N, which is O(N^2)...
More compact, using lambda:
Class getCallerClass(int nonSkippedFramesDepth) {
int[] depth = new int[1];
return Thread.fistCaller(
info -> !haveToSkip(info.getDeclaringClass()) && (++depth[0] >
nonSkippedFramesDepth),
StackFrameInfo::getDeclaringClass
);
}
Have you guys though about exposing the StackStream instead? Then you
could use all the existing JDK method for streams on that, which gives
you a much more flexible API. I could then for example change the
Stream of StackFrameInfo into one of Class.
I don't think StackStream is-a Stream<StackFrameInfo> ...
Peter
bye Jochen