请帮助我理解 JRuby 方法名称转换的不一致性。

huangapple go评论85阅读模式
英文:

Plese help me understand JRuby method name conversion inconsistensies

问题

最近,我组织了一个小项目,用于尝试使用JRuby以及它与Java的交互。这是Github gist

LogicProcessor.java:

package me.artsolopov.jrp;

import javax.swing.*;
import javax.swing.table.TableModel;
import javax.swing.text.JTextComponent;

public interface LogicProcessor {
    void actionTrig(String inst, JTextComponent anno);
    void actionClose();
    void actionAddRow();
    void setTableFilter(String filter);

    TableModel getTableModel();
}

从logic_impl.rb中的部分:

require 'java'

java_import javax.swing.table.AbstractTableModel

class LProc
  java_import Java::MeArtsolopovJrp::LogicProcessor
  include LogicProcessor

  class TableModel < AbstractTableModel
    COLUMN_NAMES = {
      q: 'Q',
      w: 'Win',
      x: 'Cross'
    }.freeze

    def initialize(data)
      super()
      @data = data
    end

    def data=(new_data)
      @data = new_data
      fire_table_data_changed
    end

    def getColumnName(col)
      COLUMN_NAMES.values[col]
    end

    def getColumnCount
      COLUMN_NAMES.count
    end

    def getRowCount
      @data.count
    end

    def getValueAt(row, col)
      col_key = COLUMN_NAMES.keys[col]
      @data[row][col_key] || 0
    end

    def isCellEditable(_r, _c)
      true
    end

    def setValueAt(value, row, col)
      col_key = COLUMN_NAMES.keys[col]
      @data[row][col_key] = Integer(value)
    end
  end

  def initialize(frame)
    @frame = frame
    @table = [
      { q: 1, w: 2, x: 3 }, { q: 2, w: 4, x: 3 },
      { q: -1, w: 5, x: 4 }, { q: 3, w: 2, x: 1 },
      { q: -2, w: 2, x: 6 }
    ]
    @slice = @table
    @table_model = TableModel.new(@slice)
  end

  attr_reader :table_model

  def action_trig(inst, anno)
    anno.text = <<~DOC
      输入的文本: #{inst}
      数据: #{@table}
    DOC
  end

  def action_close
    @frame.dispose
  end

  def action_add_row
    @table << {}
    @table_model.fire_table_rows_inserted(@table.length - 1, @table.length - 1)
  end

  def set_table_filter(filter)
    data = case filter
           when 'qpos' then @table.select { |row| row[:q].positive? }
           else @table
           end
    @table_model.data = data
  end
end

上述代码(以及gist中的代码)有效。它生成一个表单,将我的LProc实例注入表单中,我的JRuby类实现了一种业务逻辑。

但是,如果我尝试在LProc::TableModel中以snake_case形式定义方法(例如,column_nameget_column_name而不是getColumnName),我会收到错误消息,因为我没有实现抽象方法。

为什么JRuby会表现出这种方式?

英文:

Recently I've cobbled together a small project to play with JRuby and its interactions with Java. Here's the Github gist.

LogicProcessor.java:

package me.artsolopov.jrp;
import javax.swing.*;
import javax.swing.table.TableModel;
import javax.swing.text.JTextComponent;
public interface LogicProcessor {
void actionTrig(String inst, JTextComponent anno);
void actionClose();
void actionAddRow();
void setTableFilter(String filter);
TableModel getTableModel();
}

Parts from logic_impl.rb:

require &#39;java&#39;
java_import javax.swing.table.AbstractTableModel
class LProc
java_import Java::MeArtsolopovJrp::LogicProcessor
include LogicProcessor
class TableModel &lt; AbstractTableModel
COLUMN_NAMES = {
q: &#39;Q&#39;,
w: &#39;Win&#39;,
x: &#39;Cross&#39;
}.freeze
def initialize(data)
super()
@data = data
end
def data=(new_data)
@data = new_data
fire_table_data_changed
end
def getColumnName(col)
COLUMN_NAMES.values[col]
end
def getColumnCount
COLUMN_NAMES.count
end
def getRowCount
@data.count
end
def getValueAt(row, col)
col_key = COLUMN_NAMES.keys[col]
@data[row][col_key] || 0
end
def isCellEditable(_r, _c)
true
end
def setValueAt(value, row, col)
col_key = COLUMN_NAMES.keys[col]
@data[row][col_key] = Integer(value)
end
end
def initialize(frame)
@frame = frame
@table = [
{ q: 1, w: 2, x: 3 }, { q: 2, w: 4, x: 3 },
{ q: -1, w: 5, x: 4 }, { q: 3, w: 2, x: 1 },
{ q: -2, w: 2, x: 6 }
]
@slice = @table
@table_model = TableModel.new(@slice)
end
attr_reader :table_model
def action_trig(inst, anno)
anno.text = &lt;&lt;~DOC
Inputted text: #{inst}
data: #{@table}
DOC
end
def action_close
@frame.dispose
end
def action_add_row
@table &lt;&lt; {}
@table_model.fire_table_rows_inserted(@table.length - 1, @table.length - 1)
end
def set_table_filter(filter)
data = case filter
when &#39;qpos&#39; then @table.select { |row| row[:q].positive? }
else @table
end
@table_model.data = data
end
end

The code above (and in the gist) works. It produces a form, injects my LProc instance into the form, and my JRuby class implements a sort of business logic.

However, if I try to define methods in LProc::TableModel in snake_case (for example, column_name or get_column_name instead of getColumnName), I get errors because I haven't implemented abstract methods.

Why does JRuby behave that way?

答案1

得分: 4

简单的答案是:“我们还没有让类扩展以这种方式工作。” 扩展类的逻辑比实现接口的逻辑复杂得多,因此多年来我们一直不愿意对其进行重大更改。 它最初是在我们开始普及 snake_case 并改进接口实现以支持 Ruby 中等效的 camelCase 接口方法之前编写的。

简而言之,这不是一个有意的决定... 它只是一个尚未与 JRuby 的其他 Java 集成部分对齐的复杂子系统。

英文:

The simple answer is "we haven't made class extension work that way yet." The logic for extending a class is significantly more complicated than the logic for implementing an interface, and as a result we have been reluctant to make significant changes to it for many years. It was written originally before we started to make snake_case pervasive, and long before we improved interface implementation to support snake_case methods from Ruby implementing their equivalent camelCase interface methods.

In short, it's not a conscious decision... it's just a complicated subsystem that has not yet been aligned with the rest of JRuby's Java integration.

huangapple
  • 本文由 发表于 2020年8月5日 00:35:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63251312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定