2017-04-21 4 views
1

Pourquoi le code suivant indique-t-il l'erreur ci-dessous?'inclusion' d'un module, mais ne peut toujours pas appeler la méthode

require 'open3' 

module Hosts 
    def read 
    include Open3 
    popen3("cat /etc/hosts") do |i,o,e,w| 
     puts o.read 
    end 
    end 
end 

Hosts.read 
#=> undefined method `popen3' for Hosts:Class (NoMethodError) 

Il fonctionne si je l'appelle popen3 en utilisant le chemin complet à savoir Open3::popen3. Mais j'ai include -ed, alors je n'aurais pas besoin du bit Open3::?

Merci

Répondre

0

Vous avez défini une méthode d'instance, mais tentent de l'utiliser comme méthode singleton. Pour faire ce que vous voulez possible, vous aussi devez extend le Open3, non include:

module Hosts 
    extend Open3 

    def read 
    popen3("cat /etc/hosts") do |i,o,e,w| 
     puts o.read 
    end 
    end 
    module_function :read # makes it available for Hosts 
end 

maintenant:

Hosts.read 
## 
# Host Database 
# 
# localhost is used to configure the loopback interface 
# when the system is booting. Do not change this entry. 
## 
127.0.0.1 localhost 
255.255.255.255 broadcasthost 
::1    localhost 
=> nil 

lecture sur les concepts suivants Ruby va rendre les choses beaucoup plus claires pour vous:

  • contexte

  • self

  • include vs extend

Au lieu de module_fuction vous pouvez également obtenir le même résultat soit inférieur à:

module Hosts 
    extend Open3 
    extend self 

    def read 
    popen3("cat /etc/hosts") do |i,o,e,w| 
     puts o.read 
    end 
    end 
end 

Et

module Hosts 
    extend Open3 

    def self.read 
    popen3("cat /etc/hosts") do |i,o,e,w| 
     puts o.read 
    end 
    end 
end 
+0

ah, i pensait alon g ces lignes mais venir à court. Je vais lire sur 'étendre'. Et 'module_function'! Merci beaucoup. – spoovy

+0

@spoovy N/p :) Vous pourriez également réaliser le même effet avec peu plus d'options. Éditera dans un instant (juste au cas où vous êtes intéressé :)) –