arton / rjb

Ruby Java Bridge
https://www.artonx.org/collabo/backyard/?RubyJavaBridge
GNU Lesser General Public License v2.1
117 stars 34 forks source link

No way to execute method with empty params when field with the same name is present #105

Open uvlad7 opened 7 months ago

uvlad7 commented 7 months ago

So, I have java class

public class Test {
    public String test;

    public Test(String test) {
        this.test = test;
    }

    public String test() {
        return "method_" + this.test;
    }
}

and I can't call test() even with _invoke

3.0.2 :011 > Test.new("test").test
 => "test" 
3.0.2 :012 > Test.new("test")._invoke(:test)
 => "test" 

because invoke_by_instance checks if getter should be called simply by checking if argc == 0 (if that field exists), I think it should have an additional bool parameter to skip getter if it's called from rjb_i_invoke.

arton commented 6 months ago

@uvlad7 thank you for your desribed report. I implemented it at Rjb 1.7.3.

uvlad7 commented 6 months ago

@arton, thank you for the fix.

But it just hit me that I missed some nuances.

First, I assume, _invoke was added to call methods with names that are not valid ruby names, but it could be used the same fuels, and now there's no way to access a field names end, for example. So, I assume something like _field (set if arity 2, get if 1) or _set_field/_get_field is required.

Second, is it really a good idea to silently resolve this ambiguity, maybe it's better to raise an exception and force programmer to use an explicit way? Even if so, I believe it's more expected for rubyists to prefer a method over a field. I mean, we often replace

attr_reader :something

with

def something
  do_something_additional
  @something
end

and it works as public interface doesn't change, so one may expect things to work the same way if they add something() in Java. l didn't check if making something non-public helps, but we don't always can change the interface, anyway