Question

I am interested in knowing why visualvm OQL has a problem with the following statement:

select filter(heap.objects("java.util.HashMap"), isTrue(it));

function isTrue(object) {  
  return true;  
}

Exception is:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "it" is not defined. (#1)

In contrast, visualvm OQL does not have a problem with any of the following examples:

Example 1 (note "it" is not quoted):

select filter(heap.objects("java.util.HashMap"),  
    function(it) {  
      return true;  
    });

Example 2 (note "it" is quoted):

select filter(heap.objects("java.util.HashMap"), isTrue("it"));  

function isTrue(object) {  
  if (object instanceof String) {  
    throw "String passed!";  
  }  
  return true;  
}

Example 3 ("function(it)" handled specially in OQL for some reason?):

select filter(heap.objects("java.util.HashMap"), function(it) { return isTrue(it); });

function isTrue(object) {  
  return true;  
}

I ask this because it seems non-intuitive and variations of non-intuitive behavior show up unexpectedly and slow me down when I am trying to create something usable.

Was it helpful?

Solution

Your different syntaxes are not equivalent. The first:

select filter(heap.objects("java.util.HashMap"), isTrue(it));

calls isTrue with a parameter of it and passes its result to the filter() function. At that point you don't have a variable it defined, hence the error.

Your "example 1" and "example 3" both pass a function as the second parameter to the filter() function. The function you pass in is (presumably) intended as a callback that filter() will call, where the parameter it will be set by filter().

Your "example 2" is a bit like the first code in that it calls isTrue("it") immediately, but in this case it is calling it with a string literal, so you don't have a problem with the parameter being undefined. However, again this is passing the result of the function as a parameter to filter() rather than passing the function itself.

Correct usage of filter() is to pass it a function (either a function reference - the name of a function without parentheses - or a function expression like in your "example 1"). So try the following:

select filter(heap.objects("java.util.HashMap"), isTrue);

function isTrue(object) {  
  return true;  
}

// OR your example 1
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top