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

时间:2016-12-12 07:03:47

标签: ruby methods numeric

这是通过Rinda使用元组空间,我在这里有一堆“put”,看看每个步骤都发生在控制台中,但我不认为这非常重要。重要的是当我运行这段代码时:

 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

我收到错误:

  

“未定义的方法`+'用于数字:类(NoMethodError)”

为什么呢?我该如何解决?

2 个答案:

答案 0 :(得分:2)

第一个问题

(rear += 1) % n = rear

是一种有趣的写作方式:

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

这意味着:

  • rear增加1
  • n设为rear
  • 返回rear % rear,即0

你想:

rear = (rear + 1) % n

第二个问题

后部定义为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

测试

  • Lauch 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,循环无限重复。

答案 1 :(得分:1)

创建数字时,可以创建Numeric类的实例(或继承自Numeric的类)。 +方法适用于Numeric类的实例 - 它是一种实例方法。你在课堂上调用它。

Numeric是一个不寻常的类,它不会使用new来初始化类的新实例。而是直接创建数字(您不必n = Numeric.new(3) - 只需n = 3)。但是类和实例之间的关系是相同的,因为Class&#39; class方法适用于Class,实例方法(包括+)适用于实例。

可以将Ruby类视为该类实例的构建器或工厂。你实际上在创建数字而不是数字

的东西上调用了+