2013-02-26 22 views
30

Tôi đang cố gắng sử dụng các mô-đun Ruby (hỗn hợp).Ruby: mô-đun, yêu cầu và bao gồm

Tôi có test.rb:

#!/usr/bin/env ruby 
require_relative 'lib/mymodule' 

class MyApp 
    include MyModule 
    self.hallo 
end 

và lib/mymodule.rb:

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

Khá đơn giản thiết lập. Nhưng nó không hoạt động :(:?.

ruby test.rb 
test.rb:8:in `<class:MyApp>': undefined method `hallo' for MyApp:Class (NoMethodError) 
     from test.rb:6:in `<main>' 

đâu là lỗi của tôi

Trả lời

53

Tóm lại: bạn cần phải extend thay vì include mô-đun.

class MyApp 
    extend MyModule 
    self.hallo 
end 

include cung cấp phương pháp dụ cho lớp pha trộn nó trong.

extend cung cấp phương pháp lớp học cho các lớp pha trộn nó trong.

Cho this đọc.

3

Mã của bạn là làm việc - nhưng bao gồm một mô-đun không làm những gì bạn nghĩ rằng nó Các lớp bao gồm các mô-đun sẽ không nhận được . các phương pháp - các đối tượng từ lớp này sẽ

Vì vậy, đây sẽ làm việc:

class MyApp 
    include MyModule 
end 

my_app_object = MyApp.new 
my_app_object.hallo # => hallo 

my_app_object là một đối tượng của MyApp lớp, trong đó có một mixins của module MyModule T. ake xem there để có giải thích đầy đủ về các mô-đun và mixin.

8

Vấn đề là bạn đang gọi số hallo trong định nghĩa lớp, trong khi bạn thêm nó làm phương thức thể hiện (include).

Vì vậy, bạn có thể thể sử dụng extend (hallo sẽ trở thành một phương pháp học):

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

class MyApp 
    extend MyModule 
    self.hallo 
end 

Hoặc một trong hai cuộc gọi hallo trong một thể hiện của MyApp:

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

class MyApp 
    include MyModule 
end 

an_instance = MyApp.new 
an_instance.hallo 
1
class MyApp 
    class << self 
    include MyModule 
    end 
    self.hallo 
end 

cũng giống như

class MyApp 
    extend MyModule 
    self.hallo 
end 

mở rộng chỉ mở đối tượng lớp và bao gồm các phương thức mô-đun. "hallo" trở thành một đối tượng lớp. phương pháp tĩnh của lớp MyApp.

Vì vậy, "bao gồm" tiêm các phương thức vào các trường hợp của người nhận, trong trường hợp của bạn là "tự" KHÔNG với chính đối tượng đó. "mở rộng" tiêm các phương thức cho người nhận trong trường hợp của bạn là "tự".

self.include MyModule // inject the methods into the instances of self 
self.extend MyModule // inject the methods into object self 

Ở cấp độ "tự" sẽ trỏ đến đối tượng lớp học của bạn là MyApp.

Cũng nên nhớ rằng "bao gồm" và "mở rộng" chỉ là các phương thức được xác định trong mô-đun.rb. "include" là một phương thức đối tượng lớp (phương thức tĩnh) và "extend" là một phương thức cá thể.