在Ruby中使用“ nil”私有方法的目的是什么?

时间:2018-07-31 10:01:07

标签: ruby

使用ruby 2.3,然后撬起REPL,我得到了一个我无法理解的有趣结果:

nil.private_methods
# [:DelegateClass, :Digest, :sprintf, :format, :Integer, :Float, :String, :Array, :Hash, :throw, :iterator?, :block_given?, :catch, :loop, :Rational, :trace_var, :untrace_var, :Complex, :at_exit, :gem_original_require, :URI, :set_trace_func, :select, :caller, :caller_locations, :test, :fork, :`, :exit, :sleep, :respond_to_missing?, :load, :exec, :exit!, :syscall, :open, :printf, :print, :putc, :puts, :readline, :readlines, :p, :abort, :gets, :system, :spawn, :proc, :lambda, :srand, :pp, :rand, :initialize_copy, :initialize_clone, :initialize_dup, :Pathname, :trap, :gem, :BigDecimal, :require, :require_relative, :autoload, :autoload?, :binding, :local_variables, :warn, :raise, :fail, :global_variables, :__method__, :__callee__, :__dir__, :eval, :method_missing, :singleton_method_added, :singleton_method_removed, :singleton_method_undefined, :initialize]

看起来那些私有方法链接到加载的模块:

methods = nil.private_methods.dup
require "json"
nil.private_methods - methods
# [:j, :JSON, :jj]

我想知道这些私有方法的用途,并且在互联网上找不到任何相关内容。

2 个答案:

答案 0 :(得分:14)

NilClass不会自行声明任何私有实例方法。它们来自KernelBasicObject

NilClass.ancestors
#⇒ [NilClass, Object, PP::ObjectMixin, Kernel, BasicObject]
NilClass.private_instance_methods -
  (NilClass.ancestors - [NilClass]).flat_map(&:private_instance_methods)
#⇒ []

任何红宝石类都源自BasicObject,其中包括Kernel

此外,Module#private_instance_methods接受布尔参数,当设置为false时,它会禁止继承方法的输出:

NilClass.private_instance_methods false
#⇒ []
另一方面,

JSON猴子补丁NilClass除了其他所有类别:

require 'json'
NilClass.ancestors
#⇓ [NilClass, JSON::Ext::Generator::GeneratorMethods::NilClass,
#   Object, JSON::Ext::Generator::GeneratorMethods::Object,
#   PP::ObjectMixin, Kernel, BasicObject]

答案 1 :(得分:3)

以下是NilClass由所有者组织的私有方法。请注意,这些方法都不来自NilClass,模块JSONJSON中的任何嵌套模块。

require 'json'

nil.private_methods.sort.group_by { |m| NilClass.method(m).owner }
  #=> {Kernel=>[:Array, :Complex, :Float, :Hash, :Integer, :JSON, :Rational,
  #             :String, :__callee__, :__dir__, :__method__, :`, :abort,
  #             :at_exit, :binding, :block_given?, :caller, :caller_locations,
  #             :catch, :eval, :exec, :exit, :exit!, :fail, :fork, :format,
  #             :gem, :gem_original_require, :gets, :global_variables,
  #             :initialize_dup, :iterator?, :j, :jj, :lambda, :load,
  #             :local_variables, :loop, :open, :p, :print, :printf, :proc,
  #             :putc, :puts, :raise, :rand, :readline, :readlines, :require,
  #             :require_relative, :respond_to_missing?, :select, :set_trace_func,
  #             :sleep, :spawn, :sprintf, :srand, :syscall, :system, :test,
  #             :throw, :trace_var, :trap, :untrace_var, :warn],
  #    Object=>[:DelegateClass, :default_src_encoding, :irb_binding],
  #    Module=>[:autoload, :autoload?, :initialize_clone, :initialize_copy],
  #    Class =>[:initialize], BasicObject=>[:method_missing, :singleton_method_added,
  #             :singleton_method_removed, :singleton_method_undefined]}

一个人可以写

NilClass.private_instance_methods.sort.group_by { |m| NilClass.method(m).owner }

问题的第二部分询问了每种方法的目的。我将依次介绍这些。

:Array

例如,nil.send(:Array, 2) #=> [2]。我不太确定该怎么使用。

:Complex

例如,nil.send(:Complex, 2,3) #=> (2+3i)。我不太确定该怎么使用。

:Float

待完成...