BufBills
BufBills

Reputation: 8103

ruby: calling a instance method without using instance

I know in ruby, when we call an instance method, we need to firstly instantiate a class object. But when I see a open sourced code I got confused. The code is like this:

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

.....

You can see the line I marked with "<===" It uses deserialize function that been defined in message class. And from message class we can see that method is a instance method, not class method. So why can we call it without instantiating anything like this?

thanks

Upvotes: 2

Views: 1048

Answers (2)

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369428

It is being called on an instance. In Ruby, if you leave out the explicit receiver of the message send, an implicit receiver of self is assumed. So, deserialize is being called on an instance, namely self.

Note that this exact same phenomenon also occurs in other places in your code, much earlier (in line 1, in fact):

require 'fileutils'
require_relative 'message'

Here, you also have two method calls without an explicit receiver, which means that the implicit receiver is self.

Upvotes: 1

rob
rob

Reputation: 2296

Message ist an module. Your Class SimpleFile includes this module. so the module methods included in your class SimpleFile. that means, all module methods can now be used like as methods from SimpleFile

see http://ruby-doc.org/core-2.2.0/Module.html for more infos about module in ruby. it's a great feature.

Upvotes: 2

Related Questions