Есть ли у модуля Process частный метод экземпляра wait? - PullRequest
0 голосов
/ 01 июня 2018

Несколько дней назад, когда я просматривал свои документы Dash, я обнаружил странный фрагмент кода рубина.

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

Меня поразило то, что класс Object получает метод экземпляра wait, когдаон включает в себя модуль процесса.модуль Process имеет только метод класса «wait», как указано в документе.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

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

0 голосов
/ 01 июня 2018

Wait - это метод экземпляра класса Concurrent :: Event, который, в свою очередь, наследуется от Module, суперклассом которого является Object, поэтому вы можете получить доступ к методу ожидания.

Для справки:

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

...