我知道在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; ===”标记的行 它使用在消息类中定义的反序列化函数。 从消息类我们可以看到该方法是一个实例方法,而不是类方法。 那么为什么我们可以在没有实例化这样的情况下调用它呢?
感谢
答案 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
。