模块进程是否有私有实例方法'等待'?

时间:2018-06-01 04:05:49

标签: ruby module process include

几天前,当我查看我的Dash文档时,我发现了一个奇怪的ruby代码片段。

include Process
fork { exit 99 }                 #=> 27429
wait                             #=> 27429
$?.exitstatus                    #=> 99

令我震惊的是,为什么Object类在包含Process mudule时获得'wait'实例方法。 Process模块​​只有一个类方法'wait'作为文档指示。

2 个答案:

答案 0 :(得分:1)

许多Ruby stdlib模块的编写方式允许使用:

FileUtils.mkdir_p

include FileUtils
mkdir_p

这是通过使用module_function

完成的
module FileUtils
  def mkdir_p(*args)
    ...
  end
  module_function :mkdir_p
end

这使得可以将该方法用作FileUtils.mkdir_p的类方法,并在包含时将其用作实例方法mkdir_p。它包含的实例方法是私有的:

class Foo
  include FileUtils

  def test
    mkdir_p
  end
end

Foo.mkdir_p # => NoMethodError (undefined method `mkdir_p`...
Foo.new.mkdir_p # => NoMethodError (private method `mkdir_p`...
Foo.new.test # => no problem there

通过module_functionprivate_class_method一起使用,也可以将模块功能设为私有:

module AlarmClock
  def is_it_time?
    morning_yet?
  end
  module_function :is_it_time?

  def morning_yet?
    (7..11).cover?(Time.now.hour)
  end
  module_function :morning_yet?
  private_class_method :morning_yet?
end

现在你有一个使用私有模块功能的公共模块功能,你的模块仍然可以包含在另一个类/模块中并可用:

AlarmClock.morning_yet? # => NoMethodError (private method `morning_yet?' ..
AlarmClock.is_it_time? # => true

class WristWatch
  include AlarmClock

  def start_beeping
    return "beep" if is_it_time?
  end

  def stop_beeping
    return "silence" if !morning_yet?
  end
end

WristWatch.new.morning_yet? # => NoMethodError (private ..
WristWatch.new.is_it_time? # => NoMethodError (private ..
WristWatch.new.start_beeping => "beep"
WristWatch.new.stop_beeping "silence"

一些stdlib模块有一个帮助方法,不必写两个额外的行,例如fileutils.rb

module FileUtils
  def self.private_module_function(name)   #:nodoc:
    module_function name
    private_class_method name
  end
  ...
end

Process是内置的,用C语言编写,所以它不是来自process.rb,但我认为它是以类似的方式编写的。

答案 1 :(得分:-1)

Wait是一个Concurrent :: Event类的实例方法,它反过来又从其超类是Object的Module中继承,因此你可以访问wait方法。

供参考:

https://www.rubydoc.info/github/ruby-concurrency/concurrent-ruby/Concurrent%2FEvent:wait