Ruby 中数字 Class 的未定义方法“+”

Undefined Method "+" for Numeric Class in Ruby

这是通过 Rinda 使用 tuple-space,我在这里有一堆 "puts" 来查看控制台中发生的每个步骤,但我认为这不是很重要。重要的是当我 运行 这部分代码时:

 while(true)

    ts.take(["empty"])

    tag, rear = ts.read( ["rear", Numeric])
    puts "11"

    value = 7
    puts "12"

    ts.write(["buf", rear, value])
    puts "13"

    puts "have some words"
    puts "14"

    tag, rear = ts.take( ["rear", Numeric])
    puts "15"

    (rear += 1) % n = rear

    puts "16"

    ts.write(["rear", Numeric])
    puts "17"

    ts.write(["full"])
    puts "18"

    end

我收到错误:

"undefined method `+' for Numeric:Class (NoMethodError)"

为什么?我该如何解决?

创建数字时,您创建了 Numeric class 的 实例 (或继承自 Numeric). + 方法适用于 Numeric class 的实例 - 它是一个实例方法。您是在 class 本身上调用它。

Numeric 是一个不寻常的 class,因为它不使用 new 来初始化 class 的新实例。相反,数字是直接创建的(你不需要 n = Numeric.new(3) - 你只是 n = 3)。但是class和实例的关系是相同的,Class'class方法适用于Class,实例方法(包括+) 适用于实例。

Ruby classes 可以被认为是 class 实例的构建器或工厂。你实际上在创建数字的东西上调用了 + 而不是在数字上调用

第一个问题

(rear += 1) % n = rear

是一种有趣的写作方式:

(rear = rear + 1) % (n = rear)

这意味着:

  • rear 增加 1
  • n设置为rear
  • returnrear % rear,即0

你想要:

rear = (rear + 1) % n

第二题

rear 被定义为 Numericclass,而不是数字(0、1 或 3.1415...)。

它来自哪里?有一个无限循环,所以罪魁祸首可能在您收到错误的那一行之后。

1617 之间,您使用:

ts.write(["rear", Numeric])

那是你的问题。应该是:

ts.write(["rear", 3.14]) # or
ts.write(["rear", rear])

3 个脚本使其工作

01_server.rb

require 'rinda/tuplespace'

URI = "druby://localhost:61676"
DRb.start_service(URI, Rinda::TupleSpace.new)
DRb.thread.join

02_your_script.rb

require 'rinda/rinda'

URI = "druby://localhost:61676"
DRb.start_service
ts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, URI))

#######################################
# This needs to happen before your loop
ts.write(["rear", 0])
ts.write(["empty"])
n = 80
#######################################

loop do
  ts.take(["empty"])

  tag, rear = ts.read( ["rear", Numeric])
  puts "11"

  value = 7
  puts "12"

  ts.write(["buf", rear, value])
  puts "13"

  puts "have some words"
  puts "14"

  tag, rear = ts.take( ["rear", Numeric])
  puts "15"

  rear = (rear + 1) % n

  p "Rear is now : #{rear}"

  puts "16"

  # ts.write(["rear", Numeric]) # <- This was wrong. You don't want to write Numeric, the class.
  ts.write(["rear", rear])      # You want to write a Numeric, e.g. rear

  ts.write(["full"])
end

03_switch.rb

require 'rinda/rinda'

URI = "druby://localhost:61676"
DRb.start_service
ts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, URI))

loop do
  ts.take(["full"])
  ts.write(["empty"])
end

测试

  • 在终端中启动 ruby 01_server.rb
  • 在另一个终端ruby 02_your_script.rb启动

它输出:

11
12
13
have some words
14
15
"Rear is now : 1"
16

循环停止,等待"empty"

  • 在另一个终端中启动 03_switch.rb,循环无限重复。