【问题标题】:Undefined Method "+" for Numeric Class in RubyRuby中数值类的未定义方法“+”
【发布时间】:2016-12-12 07:03:46
【问题描述】:

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

 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

我得到错误:

"未定义的方法 `+' for Numeric:Class (NoMethodError)"

为什么?我该如何解决?

【问题讨论】:

  • NoMethodError 具体是在哪里提出的?你希望(rear += 1) % n = rear 做什么?
  • “puts 15”后停止运行并返回错误。我希望它在后面加上 1,然后对 n 取模。 n 在代码前面定义为 80
  • 返回相同的错误。我认为问题不在于赋值语句,而在于 Numeric 类的工作原理?
  • puts rear.inspectputs "15" 之后返回什么?
  • 它只返回:数字

标签: ruby methods numeric


【解决方案1】:

第一个问题

(rear += 1) % n = rear

是一种有趣的写作方式:

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

这意味着:

  • rear 增加 1
  • n 设置为rear
  • 返回rear % 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,循环无限重复。

【讨论】:

  • 大声笑,是的,这是一种愚蠢的输入方式,但我之所以这样做,是因为我实际上已经尝试过 back = (rear + 1) % n 并且它返回了同样该死的错误。老实说,我只是想再次询问我的教授,如果他不知道,我就继续前进,我还有其他决赛 =.=
  • 那是第二个问题。第一个问题仍然存在。您如何以及在何处定义您的价值观?
  • " ts.write(["rear", rear]) " 是的,这让它看起来运行良好!我猜rear 是Numeric 类的一个实例的名称,而我之前将rear 称为Numeric 类本身?无论如何,谢谢朋友!
  • 没错。很高兴,学习 Rinda 很有趣,我以前从未使用过。
【解决方案2】:

当您创建数字时,您会创建Numeric 类(或继承自Numeric 的类)的实例+ 方法适用于 Numeric 类的实例——它是一个实例方法。你在类本身上调用它。

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

Ruby 类可以被认为是该类实例的构建器或工厂。您实际上在创建数字而不是数字的事物上调用了+

【讨论】:

  • 好的,这是有道理的(尤其是在阅读了 Numeric 类之后)。你有什么建议我尝试解决这个问题?我已经阅读了一些使用类似的建议
  • ts.take([Numeric]) 应该返回一个 Numeric 实例,并且它似乎返回了 Numeric 类。这没有意义,至少根据我找到的几个例子来说不是。
猜你喜欢
  • 2016-06-30
  • 2018-05-16
  • 1970-01-01
  • 2013-04-28
  • 2020-01-03
  • 1970-01-01
  • 2019-12-25
  • 2010-10-15
  • 1970-01-01
相关资源
最近更新 更多