2009-12-11 37 views
41
obj = SomeObject.new 

def obj.new_method 
    "do some things" 
end 

puts obj.new_method 
> "do some things" 

Tác phẩm này ok. Tuy nhiên, tôi cần phải làm điều tương tự bên trong một phương pháp hiện có:Thêm phương thức vào một đối tượng được sao chép

def some_random_method 
    def obj.new_method 
    "do some things" 
    end 
end 

Hoạt động tốt, nhưng có phương pháp bên trong phương pháp trông khá khủng khiếp. Câu hỏi đặt ra là, có cách nào khác để thêm phương thức như vậy không?

+0

Bạn có chắc đoạn mã thứ hai hoạt động không? Bởi vì tôi cho rằng nó nên chấp nhận 'obj' như một đối số phương thức đầu tiên để định nghĩa một phương thức singleton trên nó. – Chirantan

Trả lời

66

Nó được một thời gian dài kể từ khi tôi hỏi này. Trong ruby ​​1.9+, có cách tốt hơn để thực hiện việc này bằng cách sử dụng define_singleton_method, như sau:

obj = SomeObject.new 

obj.define_singleton_method(:new_method) do 
    "do some things" 
end 
+2

Điều gì sẽ xảy ra nếu tôi sử dụng '@ field' bên trong khối' do' này? Tôi sẽ truy cập một trường từ lớp hiện tại, hoặc nó sẽ sử dụng trường 'obj'? – ciembor

+1

Đã không thực sự thử nghiệm điều này đúng cách, nhưng theo như tôi có thể nói mixin và cách tiếp cận này là không tương đương. Điều này có quyền truy cập vào các giá trị bên ngoài, trong khi một mixin thì không. – vise

43

Sử dụng Mixin.

module AdditionalMethods 
    def new_method 
    "do some things" 
    end 
end 

obj = SomeObject.new 
obj.extend(AdditionalMethods) 

puts obj.new_method 
> "do some things" 
6

Bạn có thể sử dụng mô-đun.

module ObjSingletonMethods 
    def new_method 
    "do some things" 
    end 
end 


obj.extend ObjSingletonMethods 

puts obj.new_method # => do some things 

Bây giờ nếu bạn cần thêm nhiều phương thức vào đối tượng đó, bạn chỉ cần triển khai các phương thức trong mô-đun và bạn đã hoàn tất.

7

Chỉ cần một điểm thú vị cần lưu ý:

nếu bạn đã thay đi:

def my_method 
    def my_other_method; end 
end 

Sau đó my_other_method sẽ thực sự được xác định trên CLASS của đối tượng không chịu được mà người nhận my_method là một ví dụ .

Tuy nhiên nếu bạn đi (như bạn đã làm):

def my_method 
    def self.my_other_method; end 
end 

Sau đó my_other_method được định nghĩa trên eigenclass của instance.

Không có liên quan trực tiếp đến câu hỏi của bạn nhưng loại thú vị dù sao;)

Các vấn đề liên quan