Многие модули 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
, но я предполагаю, что он был написанв подобной манере.