几天前,当我查看我的Dash文档时,我发现了一个奇怪的ruby代码片段。
include Process
fork { exit 99 } #=> 27429
wait #=> 27429
$?.exitstatus #=> 99
令我震惊的是,为什么Object类在包含Process mudule时获得'wait'实例方法。 Process模块只有一个类方法'wait'作为文档指示。
答案 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_function
与private_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