Ruby方法范围问题

时间:2014-05-14 05:56:47

标签: ruby multithreading scope

我正在学习ruby,我试图在模块中创建一个类,然后在另一个脚本中使用该类。这是我的模块:

#!/usr/bin/ruby -w

module RubyMine
  require 'thread'

  puts "loading"
  class Address
    def initialize(host, port)
      @host = host
      @port = port
    end

    def host
      @host
    end

    def port
      @port
    end
  end

  class Node
    def initialize(address)
      puts "Initializing..."
      @address = address
      @controller = nil
      puts "...initialized."
    end

    def stopin
      puts "Stopping..."
      Thread.kill(@controller)
      puts "...stopped."
    end

    def startin
      puts "Starting..."
      @controller = Thread.start do
        puts "Thread Starting..."
        listener = tcpserver.new(address.host, address.port)
        loop do
          Thread.start(listener.accept) do |s|
            loop do
              msg = s.gets.chomp
              break unless msg.length > 0
              puts msg
            end
          end
        end
        puts "Thread stopping."
      end
      puts "...started."
    end
  end
end

出于某种原因,每当我尝试拨打startinstopin时,我都会收到错误./test.rb:8:in&#39 ;:未定义的方法startin' for #<RubyMine::Node:0xb243e8> (NoMethodError)

以下是我用来调用模块的脚本:

#!/usr/bin/ruby -w

require '~/rubymine1/rubymine'

add = RubyMine::Address.new("127.0.0.1", 20000)
node = RubyMine::Node.new(add)
puts RubyMine::Node.methods
node.startin
sleep 4
node.stopin

我一直在查看示例和在线教程,但据我所知,一切都应该有效。有什么想法吗?

- 编辑5/14 - 我忘了提到的另一件事,当我命名为&#39; startin&#39; &#39;开始&#39;,它跑了。我认为这是因为它覆盖了现有的方法。不知道这是否有帮助。

1 个答案:

答案 0 :(得分:0)

您的代码似乎没问题,至少我可以在没有问题的情况下在irb中运行它。我无法telnet到服务器。出于这个原因,我不明白为什么你得到NoM​​ethodError,我没有这些问题。但行

puts RubyMine::Node.methods

会给你带来误导性的结果,因为你向类对象询问它的方法。为了了解node对象的方法,您应该问它,例如如下:

node.methods.select do |m| m.match /start/ end

(所以你只能获得一行输出,但是相关的一行)。正如预期的那样显示

=> [:startin]
对我来说。你能试试吗?

修改

正如我所说,我在irb 1.9 ruby会话中运行了这个,我碰巧在终端开了,我得到了以下结果:

irb(main):104:0> add = RubyMine::Address.new("127.0.0.1", 20000)
=> #<RubyMine::Address:0x007fbdaa8a05b0 @host="127.0.0.1", @port=20000>
irb(main):105:0> node = RubyMine::Node.new(add)
Initializing...
...initialized.
=> #<RubyMine::Node:0x007fbdaa898888 @address=#<RubyMine::Address:0x007fbdaa8a05b0 @host="127.0.0.1", @port=20000>, @controller=nil>
irb(main):106:0> node.methods.select do |m| m.match /start/ end
=> [:startin]
irb(main):107:0> node.startin
Starting...
...started.
=> nil
Thread Starting...irb(main):108:0> sleep 10

=> 10
irb(main):109:0> node.stopin
Stopping...
...stopped.

我认为这应该是你所期望的。但请注意我得到了

> telnet 127.0.0.1 20000
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host

即使服务器正在运行。也许你可以在irb中运行你的代码,你会看到更多可能无效的代码。您还应该提到正在运行的ruby版本。