Instance Functions as Closures?

2006-07-25
2013-04-19
  • andrew cooke

    andrew cooke - 2006-07-25

    I'm confused.  I am trying to use Functions.filter with an InstanceFunction, but the filter seems to be using the list values as objects rather than parameters.

    I have code like:
    Function f = new InstanceFunction(class, "name").object(instance);
    Functions.filter(f, list).

    Given that the instance function already has an instance, shouldn't the filter treat the list contents as parameters ("name" takes a single argument)?

    How do I achieve this?

    As a concrete example, say I want to filter a list to find all those entries which are ".equal()" to some instance.  That doesn't seem to be possible using Functions.filter?!

     
    • andrew cooke

      andrew cooke - 2006-07-25

      (The error I am seeing is:
      info.javelot.functionalj.FunctionException: The object() method was called with parameter [org.acooke.collaborate.data.transport.exchanges.ParticipantContacts@6bc947], but another object was previously supplied to the function [org.acooke.collaborate.presentation.model.aspects.exchange.ExchangeEmailsLogic$IsCentre@6b5488].)

       
      • Fred Daoud

        Fred Daoud - 2006-07-26

        Hi Andrew,

        Indeed, when an instance function already has an instance, the filter will consider the list contents as parameters.

        The problem seems to be how you create your instance function. To specify an object as the instance, you have two options. Either specify a class, then use the object() method to specify the instance object, or specify the object directly. But not both - you seem to be doing both. Here are two examples to use the "equalsIgnoreCase" of a string:

        String string = "Abc";

        Function f1 = new InstanceFunction(String.class, "equalsIgnoreCase").object(string);

        Function f2 = new InstanceFunction(string, "equalsIgnoreCase");

        However this will cause the exception that you mentioned:

        Function wrong = new InstanceFunction(string, "equalsIgnoreCase").object(string);

        because you are specifying the object twice.

        Finally, here is an example of using the filter with such a function:

        String string = "Abc";

        Function f = new InstanceFunction(string, "equalsIgnoreCase");

        String[] strings = {"ab", "bc", "Abc", "ABC", "A", "abc"};

        List result = Functions.filter(f, strings);

        System.out.println(result);

        will print out

        [Abc, ABC, abc]

        Hope this helps!

        Frederic
        Frederic

         
    • andrew cooke

      andrew cooke - 2006-07-25

      ok, so i can fix this by inverting the approach, making the function definition be appropriate for the "instances" in the list, and making my original single object a parameter.

      however, that makes it difficult to use the single initial object as a closure.  seems like it would be best to have both options.

       
    • andrew cooke

      andrew cooke - 2006-07-26

      hmmm.  your answer was convincing, but when i tried it, i still saw the error.  it turns out that it seems to be bug in filterNot, and that i over-simplified things in my previous description.

      here's a better descripion of the problem - the second test below (the one with filterNot) gives the runtime exception i described earlier.

      public void test1() {
      assertEquals(
        Functions.filter(
         new InstanceFunction(new Integer(3), "equals"),
         new Object[]{1,2,3,4}).size(),
        1);
      }

      public void test2() {
      assertEquals(
        Functions.filterNot(
         new InstanceFunction(new Integer(3), "equals"),
         new Object[]{1,2,3,4}).size(),
        3);
      }

      thanks for replying so quickly!

       

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks