2

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.

PineForest
  • 75
  • 1
  • 9

1 Answers1

5

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
nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • Thank you very much, @nnnnnn. I learned several things about JavaScript and OQL from your example and details. – PineForest Dec 11 '11 at 08:15
  • 1
    For example, @nnnnnn, I should have used (typeof object=="string") as my comparator in example #2 (based on your reply I researched why the if statement did not catch the string being passed!). Also, I was building on my flawed examples to create more complicated and flawed statements: filter(array, childOfMyClass("it","referrers(it)")) is an example where childOfMyClass is passed two parameters and I now can see is obviously wrong. I changed it to take one parameter and I pass the filter childOfMyClass without the argument list. – PineForest Dec 11 '11 at 08:32