请帮助我理解 JRuby 方法名称约定不一致的问题
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
Inputted text: #{inst}
data: #{@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
上面的代码(和要点中的)有效。它生成一个表单,将我的 LProc
实例注入表单,然后我的 JRuby class 实现了一种业务逻辑。
但是,如果我尝试在 snake_case 中定义 LProc::TableModel
中的方法(例如,column_name
或 get_column_name
而不是 getColumnName
),我得到错误,因为我还没有实现抽象方法。
为什么 JRuby 会这样?
简单的回答是“我们还没有 class 以这种方式进行扩展。”扩展 class 的逻辑比实现接口的逻辑要复杂得多,因此多年来我们一直不愿对其进行重大更改。它最初是在我们开始使 snake_case 普及之前编写的,并且早在我们改进接口实现以支持 Ruby 中的 snake_case 方法实现其等效的 camelCase 接口方法之前。
简而言之,这不是一个有意识的决定...它只是一个复杂的子系统,尚未与 JRuby 的 Java 集成的其余部分保持一致。
最近我拼凑了一个小项目来使用 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
Inputted text: #{inst}
data: #{@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
上面的代码(和要点中的)有效。它生成一个表单,将我的 LProc
实例注入表单,然后我的 JRuby class 实现了一种业务逻辑。
但是,如果我尝试在 snake_case 中定义 LProc::TableModel
中的方法(例如,column_name
或 get_column_name
而不是 getColumnName
),我得到错误,因为我还没有实现抽象方法。
为什么 JRuby 会这样?
简单的回答是“我们还没有 class 以这种方式进行扩展。”扩展 class 的逻辑比实现接口的逻辑要复杂得多,因此多年来我们一直不愿对其进行重大更改。它最初是在我们开始使 snake_case 普及之前编写的,并且早在我们改进接口实现以支持 Ruby 中的 snake_case 方法实现其等效的 camelCase 接口方法之前。
简而言之,这不是一个有意识的决定...它只是一个复杂的子系统,尚未与 JRuby 的 Java 集成的其余部分保持一致。