ruby:在不使用实例的情况下调用实例方法

时间:2015-06-28 04:39:03

标签: ruby class object methods

我知道在ruby中,当我们调用实例方法时,我们需要首先实例化一个类对象。 但当我看到一个开源代码时,我感到困惑。 代码是这样的:

File Message.rb
require 'json'

module Yora
  module Message
    def serialize(msg)
      JSON.generate(msg)
    end

    def deserialize(raw, symbolized_key = true)
      msg = JSON.parse(raw, create_additions: true)
      if symbolized_key
        Hash[msg.map { |k, v| [k.to_sym, v] }]
      else
        msg
      end
    end
  end
end



File. Persistance.rb


require 'fileutils'
require_relative 'message'

module Yora
  module Persistence
    class SimpleFile
      include Message

      def initialize(node_id, node_address)
        @node_id, @node_address = node_id, node_address

        FileUtils.mkdir_p "data/#{node_id}"

        @log_path = "data/#{node_id}/log.txt"
        @metadata_path = "data/#{node_id}/metadata.txt"
        @snapshot_path = "data/#{node_id}/snapshot.txt"
      end

      def read_metadata
        metadata = {
          current_term: 0,
          voted_for: nil,
          cluster: { @node_id => @node_address }
        }
        if File.exist?(@metadata_path)
          metadata = deserialize(File.read(@metadata_path)) #<============
        end

        $stderr.puts "-- metadata = #{metadata}"

        metadata
      end

.....

你可以看到我用“&lt; ===”标记的行 它使用在消息类中定义的反序列化函数。 从消息类我们可以看到该方法是一个实例方法,而不是类方法。 那么为什么我们可以在没有实例化这样的情况下调用它呢?

感谢

2 个答案:

答案 0 :(得分:2)

Message是一个模块。您的班级SimpleFile包含此模块。所以您的班级SimpleFile中包含的模块方法。这意味着,现在可以像SimpleFile

中的方法一样使用所有模块方法

有关ruby中模块的更多信息,请参阅http://ruby-doc.org/core-2.2.0/Module.html。这是一个很棒的功能。

答案 1 :(得分:1)

在实例上调用 。在Ruby中,如果省略了消息send的显式接收者,则假定为self的隐式接收者。因此,deserialize 在实例上被调用,即self

请注意,在代码中的其他位置也会发生这种完全相同的现象,更早一些(实际上在第1行):

require 'fileutils'
require_relative 'message'

在这里,您还有两个没有显式接收器的方法调用,这意味着隐式接收器是self