Why does the following code give the error below?
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)
It works if I call popen3
using full path ie Open3::popen3
. But I've include
-ed it, so thought I wouldn't need the Open3::
bit?
Thanks
You have defined an instance method, but are trying to use it as singleton method. To make what you want possible, you also have to extend
the Open3
, not 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
Now:
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
Reading about the following concepts in Ruby will make things much clearer for you:
context
self
include
vs extend
Instead of module_fuction
you could also achieve the same result with either of below:
module Hosts
extend Open3
extend self
def read
popen3("cat /etc/hosts") do |i,o,e,w|
puts o.read
end
end
end
And
module Hosts
extend Open3
def self.read
popen3("cat /etc/hosts") do |i,o,e,w|
puts o.read
end
end
end