This is using tuple-space via Rinda and I have a bunch of "puts" in here to see each step happen in the console but I don't think that's very important. What IS important is when I run this section of code:
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
I get the error:
"undefined method `+' for Numeric:Class (NoMethodError)"
Why? How do I fix this?
(rear += 1) % n = rear
is a funny way of writing :
(rear = rear + 1) % (n = rear)
Which means :
rear
by 1 n
to rear
rear % rear
, which is 0
You want :
rear = (rear + 1) % n
rear is defined as Numeric
, the class , not as a Numeric (0, 1 or 3.1415...).
Where does it come from? There's an infinite loop, so the culprit could be after the line in which you get the error.
Between 16
and 17
, you use :
ts.write(["rear", Numeric])
and that's your problem. It should be :
ts.write(["rear", 3.14]) # or
ts.write(["rear", rear])
require 'rinda/tuplespace'
URI = "druby://localhost:61676"
DRb.start_service(URI, Rinda::TupleSpace.new)
DRb.thread.join
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
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
in a terminal ruby 02_your_script.rb
in another terminal It outputs :
11
12
13
have some words
14
15
"Rear is now : 1"
16
The loop stops, waiting for "empty"
.
03_switch.rb
in yet another terminal, and the loop repeats infinitely. When you create a number, you create an instance of the Numeric
class (or a class that inherits from Numeric
). The +
method applies to instances of the Numeric
class - it is an instance method. You are calling it on the class itself.
Numeric is an unusual class in that it doesn't use new
to initialize new instances of the class. Instead numbers are created directly (you don't do n = Numeric.new(3)
- you just n = 3
). But the relationship between the class and the instance is the same in that the Class' class methods apply to the Class, and the instance methods (including +
) apply to the instances.
Ruby classes can be thought of as builders or factories for instances of that class. You have in effect called +
on the thing that creates numbers rather than on a number
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.