Ruby 中的子类构造函数
Subclasses constructor in Ruby
尝试用 classes 在 Ruby 中构建一个可编程计算器,它可以通过各种操作进行扩展。逻辑:首先用Calculator.new
初始化计算器class,然后将命令添加为子class,如Calculator.new.add_command (“+”, ClassName)
.
我未能弄清楚如何使用 class 方法自动创建子 classes,但通过 Ruby 的内置 public_send method
,所以代码看起来像这样:
class Calculator
attr_accessor :num1, :calc
def initialize(num1)
@num1 = num1
@calc = []
end
def compute(operation, num)
if @calc.length == 0
@calc[0] = @num1.public_send(operation, num)
else
@calc[0] = @calc[0].public_send(operation, num)
end
end
def result
@calc[0]
end
end
cal = Calculator.new(1)
cal.compute(:+, 1)
p cal.result => 2
有没有办法用 class 方法构建子 classes 并向它们传递像 public_send
这样的功能?
此外,计算器也不是传统的计算器:在初始化阶段它应该接受一个参数,即第一个数字,接下来的每个操作都应该接受第二个数字并与前一个操作的结果一起工作。喜欢:
Calculator.new(1)
cal.compute(“+”, 2) => 1 + 2 = 3
cal.compute(“-”, 1) => 3 - 1 = 2
cal.compute(“**”, 2) => 2 ** 2 = 4
您可以使用哈希 (@commands
) 将操作映射到它们各自的 class 或模块:
class Calculator
attr_accessor :num1, :calc
def initialize(num1)
@num1 = num1
@calc = []
@commands = {}
end
def add_command(operation, callable)
@commands[operation] = callable
end
# ...
end
您还需要对方法名称进行一些约定,让我们选择 call
:
class Calculator
# ...
def compute(operation, num)
if @calc.length == 0
@calc[0] = @commands[operation].call(@num1, num)
else
# ...
end
end
# ...
end
现在您只需要一个响应 call
的对象,例如具有 class 方法的模块:
module Addition
def self.call(a, b)
a + b
end
end
要将 Addition
添加为 :+
操作:
cal = Calculator.new(2)
cal.add_command(:+, Addition)
cal.compute(:+, 3)
cal.result #=> 5
您还可以添加一个 proc / lambda 因为它们也响应 call
:
cal = Calculator.new(2)
cal.add_command :+, ->(a, b) { a + b }
cal.compute(:+, 3)
cal.result #=> 5
尝试用 classes 在 Ruby 中构建一个可编程计算器,它可以通过各种操作进行扩展。逻辑:首先用Calculator.new
初始化计算器class,然后将命令添加为子class,如Calculator.new.add_command (“+”, ClassName)
.
我未能弄清楚如何使用 class 方法自动创建子 classes,但通过 Ruby 的内置 public_send method
,所以代码看起来像这样:
class Calculator
attr_accessor :num1, :calc
def initialize(num1)
@num1 = num1
@calc = []
end
def compute(operation, num)
if @calc.length == 0
@calc[0] = @num1.public_send(operation, num)
else
@calc[0] = @calc[0].public_send(operation, num)
end
end
def result
@calc[0]
end
end
cal = Calculator.new(1)
cal.compute(:+, 1)
p cal.result => 2
有没有办法用 class 方法构建子 classes 并向它们传递像 public_send
这样的功能?
此外,计算器也不是传统的计算器:在初始化阶段它应该接受一个参数,即第一个数字,接下来的每个操作都应该接受第二个数字并与前一个操作的结果一起工作。喜欢:
Calculator.new(1)
cal.compute(“+”, 2) => 1 + 2 = 3
cal.compute(“-”, 1) => 3 - 1 = 2
cal.compute(“**”, 2) => 2 ** 2 = 4
您可以使用哈希 (@commands
) 将操作映射到它们各自的 class 或模块:
class Calculator
attr_accessor :num1, :calc
def initialize(num1)
@num1 = num1
@calc = []
@commands = {}
end
def add_command(operation, callable)
@commands[operation] = callable
end
# ...
end
您还需要对方法名称进行一些约定,让我们选择 call
:
class Calculator
# ...
def compute(operation, num)
if @calc.length == 0
@calc[0] = @commands[operation].call(@num1, num)
else
# ...
end
end
# ...
end
现在您只需要一个响应 call
的对象,例如具有 class 方法的模块:
module Addition
def self.call(a, b)
a + b
end
end
要将 Addition
添加为 :+
操作:
cal = Calculator.new(2)
cal.add_command(:+, Addition)
cal.compute(:+, 3)
cal.result #=> 5
您还可以添加一个 proc / lambda 因为它们也响应 call
:
cal = Calculator.new(2)
cal.add_command :+, ->(a, b) { a + b }
cal.compute(:+, 3)
cal.result #=> 5