deeplyloving / lambdaj

Automatically exported from code.google.com/p/lambdaj
Apache License 2.0
0 stars 0 forks source link

Proxying access to a collection does not work #82

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Please excuse if this issue is non-valid based on my little understanding of 
Lambda-J...

I try to proxy access to a collection member which breaks with a NPE. Proxying 
methods with parameters works in general. Please confirm this is a bug or close 
it as invalid if I get something wrong. Here's a JUnit testcase to demonstrate 
the issue:

public class LambdaTest
{
    @Test
    public void testArrayAccess()
    {
        try
        {
            final String proxiedNameOfVaccumCleaner = Lambda.on(LambdaBean.class).tubbies.get(4);
        }
        catch (NullPointerException e)
        {
            // here goes the BOOM!!!
            fail("why?");
        }
    }

    @Test
    public void testMethodWithParam()
    {
        final int proxiedCalulationResult = Lambda.on(LambdaBean.class).value(4);
        final Argument<Integer> argument = ArgumentsFactory.actualArgument(proxiedCalulationResult);
        assertEquals(new Integer(24), argument.evaluate(new LambdaBean(2)));
        assertEquals(new Integer(48), argument.evaluate(new LambdaBean(4)));
    }

    private static class LambdaBean
    {
        private final List<String> tubbies;
        private final int base;

        private LambdaBean(int base)
        {
            this.base = base;

            this.tubbies = new ArrayList<String>();
            this.tubbies.add("Tinky-Winky");
            this.tubbies.add("Dipsy");
            this.tubbies.add("Laa-Laa");
            this.tubbies.add("Po");
            this.tubbies.add("Noo-Noo");
        }

        public int value(int arg)
        {
            return arg * 3 * base;
        }
    }
}

Original issue reported on code.google.com by pete4...@gmail.com on 26 Jan 2012 at 12:09

GoogleCodeExporter commented 9 years ago
an updated test case with field and method access to the collection, both 
breaking...

public class LambdaTest
{
    @Test
    public void testArrayAccessWithField()
    {
        try
        {
            final String proxiedNameOfVaccumCleaner = Lambda.on(LambdaBean.class).tubbies.get(4);
        }
        catch (NullPointerException e)
        {
            // here goes the BOOM!!!
            fail("why?");
        }
    }

    @Test
    public void testArrayAccessWithMethod()
    {
        try
        {
            final String proxiedNameOfVaccumCleaner = Lambda.on(LambdaBean.class).getTubbies().get(4);
        }
        catch (ClassCastException e)
        {
            // here goes another BOOM!!!
            fail("why?");
        }
    }

    @Test
    public void testMethodWithParam()
    {
        final int proxiedCalulationResult = Lambda.on(LambdaBean.class).value(4);
        final Argument<Integer> argument = ArgumentsFactory.actualArgument(proxiedCalulationResult);
        assertEquals(new Integer(24), argument.evaluate(new LambdaBean(2)));
        assertEquals(new Integer(48), argument.evaluate(new LambdaBean(4)));
    }

    private static class LambdaBean
    {
        private final List<String> tubbies;
        private final int base;

        private LambdaBean(int base)
        {
            this.base = base;

            this.tubbies = new ArrayList<String>();
            this.tubbies.add("Tinky-Winky");
            this.tubbies.add("Dipsy");
            this.tubbies.add("Laa-Laa");
            this.tubbies.add("Po");
            this.tubbies.add("Noo-Noo");
        }

        public List<String> getTubbies()
        {
            return tubbies;
        }

        public int value(int arg)
        {
            return arg * 3 * base;
        }
    }
}

Original comment by pete4...@gmail.com on 26 Jan 2012 at 12:13

GoogleCodeExporter commented 9 years ago
This is a misunderstanding of how lambdaj works. In particular 

1. erasure doesn't allow lambdaj to figure out at runtime that it's dealing 
with a List of String, so, under the lambdaj point of view, List.get() just 
returns a generic object
2. doesn't make much sense to use on() in this way, but it should be used in 
together with other lambdaj methods
3. the on() method cannot work on method returning a final class like String

Original comment by mario.fu...@gmail.com on 29 Jan 2012 at 6:58