k-yamadaのブログ

プログラミングのメモ

JRubyで継承元のメソッドをオーバーライドする場合は、メソッド名をアンスコ区切りに変えてはいけない

普通、Javaでキャメルケース(例:setName)で定義されているメソッドは、JRubyからアンスコ区切り(例:set_name)で呼び出す事ができるのですが、継承でオーバーライドするメソッドの場合はうまくいかないようです。


継承元クラス(一部のみ抜粋)

package com.android.ddmlib;

public abstract class MultiLineReceiver implements IShellOutputReceiver {

     public final void addOutput(byte[] data, int offset, int length) {
        if (isCancelled() == false) {
            String s = null;
            try {
                s = new String(data, offset, length, "ISO-8859-1"); //$NON-NLS-1$
            } catch (UnsupportedEncodingException e) {
                // normal encoding didn't work, try the default one
                s = new String(data, offset,length);
            }

            // ok we've got a string
            if (s != null) {
                // if we had an unfinished line we add it.
                if (mUnfinishedLine != null) {
                    s = mUnfinishedLine + s;
                    mUnfinishedLine = null;
                }

                // now we split the lines
                mArray.clear();
                int start = 0;
                do {
                    int index = s.indexOf("\r\n", start); //$NON-NLS-1$

                    // if \r\n was not found, this is an unfinished line
                    // and we store it to be processed for the next packet
                    if (index == -1) {
                        mUnfinishedLine = s.substring(start);
                        break;
                    }

                    // so we found a \r\n;
                    // extract the line
                    String line = s.substring(start, index);
                    if (mTrimLines) {
                        line = line.trim();
                    }
                    mArray.add(line);

                    // move start to after the \r\n we found
                    start = index + 2;
                } while (true);

                if (mArray.size() > 0) {
                    // at this point we've split all the lines.
                    // make the array
                    String[] lines = mArray.toArray(new String[mArray.size()]);

                    // send it for final processing
                    processNewLines(lines);
                }
            }
        }
    }

    public abstract void processNewLines(String[] lines);
}


processNewLinesメソッドをアンスコ区切りにするとエラーが発生

  class CollectingOutputReceiver < com.android.ddmlib.MultiLineReceiver
    def initialize
      puts "initialize"
      @output_buffer = ""
    end

    def get_output
      return @output_buffer.toString();
    end

    # @Override
    def process_new_lines(lines) 
      lines.each do |line|
        @output_buffer << line + "\n"
      end
    end

    # @Override
    def isCancelled
      return false;
    end
  end

Failure/Error: Unable to find matching line from backtrace
Java::JavaLang::AbstractMethodError:
# com.android.ddmlib.MultiLineReceiver.addOutput(MultiLineReceiver.java:99)
# com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:419)
# com.android.ddmlib.Device.executeShellCommand(Device.java:277)

processNewLinesをキャメルケース(Javaクラスで定義されているものと同じ)にすればOK

  class CollectingOutputReceiver < com.android.ddmlib.MultiLineReceiver
    def initialize
      puts "initialize"
      @output_buffer = ""
    end

    def get_output
      return @output_buffer.toString();
    end

    # @Override
    def processNewLines(lines) 
      lines.each do |line|
        @output_buffer << line + "\n"
      end
    end

    # @Override
    def isCancelled
      return false;
    end
  end