2009-09-14 38 views
16

Tôi muốn lưu trữ một số phương thức khác nhau trong một mảng trong Ruby. Giả sử tôi muốn để lưu trữ các phương pháp type hai lần:Con trỏ phương pháp trong ruby ​​

[type, type] 

không lưu trữ hai mục của type trong một mảng; nó thực hiện type hai lần và lưu trữ các kết quả trong mảng. làm cách nào để tôi tham chiếu một cách rõ ràng với đối tượng phương thức?

(đây chỉ là một phiên bản đơn giản của những gì tôi thực sự muốn.)

EDIT: trên những suy nghĩ thứ hai, nó làm tôi bực mình rằng giải pháp đề xuất dưới đây tránh được vấn đề bằng cách truyền tên của phương pháp. làm thế nào để bạn vượt qua đối tượng phương pháp chính nó? ví dụ: nếu bạn chuyển [: type,: type] thành phương thức có độ phân giải thay thế cho loại? làm thế nào bạn có thể vượt qua các đối tượng phương pháp loại chính nó?

Trả lời

31

Nếu bạn muốn lưu trữ một phương pháp chứ không phải là kết quả của việc gọi một phương thức hay chỉ là thông điệp mà bạn muốn gửi để gọi nó, bạn cần sử dụng phương thức method trên đối tượng sở hữu. Vì vậy, ví dụ

"hello".method(:+) 

sẽ trở lại với phương pháp + của đối tượng "hello", do đó nếu bạn gọi nó với lập luận "thế giới", bạn sẽ nhận được "hello world".

helloplus = "hello".method(:+) 
helloplus.call " world" # => "hello world" 
+0

[phương thức (: loại), phương thức (: loại)] – jrhicks

+0

@jrhicks: Chỉ khi các phương thức thuộc về bản thân. – Chuck

+0

Huy hiệu SO Ruby đầu tiên - chúc mừng! –

1
[:type, :type].collect { |method_name| self.send(method_name) } 

Ngoài ra, nếu phương pháp này là một phần của một đối tượng:

method = obj.method(:type) 
values = [method.call, method.call] 
+0

điều này dường như không hiệu quả đối với tôi - nó chỉ dẫn đến '[Object, Object]'. – Peter

+0

Phần đầu tiên của câu trả lời về cơ bản đã được sao chép từ irb, vì vậy tôi cho rằng sự đơn giản hóa tình huống của bạn là vặn nó lên. –

+0

Có vẻ phù hợp với tôi. Kiểu Object là Object ... Bạn có thể muốn 'self.send (method_name)' để nó áp dụng phương thức cho đối tượng của bạn chứ không phải đối tượng Object toàn cục. –

11

Nếu bạn đang nghĩ đến việc thực hiện các tham chiếu phương pháp trong Ruby, bạn đang làm sai.

Có một phương pháp tích hợp trong Ruby được gọi là method. Nó sẽ trả về một phiên bản proc của phương thức. Nó không phải là một tham chiếu đến phương pháp ban đầu, mặc dù; mọi cuộc gọi đến method sẽ tạo một proc mới. Thay đổi phương pháp sẽ không ảnh hưởng đến proc, ví dụ.

def my_method 
    puts "foo" 
end 

copy = method(:my_method) 

# Redefining 
def my_method 
    puts "bar" 
end 

copy.call 
# => foo 

Khi bạn muốn lưu trữ các đoạn mã và không muốn sử dụng các phương pháp thông thường, hãy sử dụng procs.

stack = [proc { do_this }, proc { do_that }] 
stack.each {|s| s.call } 
+0

Như tôi đã nói trong phần bình luận cho câu trả lời của tôi, đó chính là cách nó hoạt động. Bạn không "thay đổi phương thức", bạn thay thế phương thức. Rõ ràng là một tham chiếu đến phương thức cũ sẽ vẫn tham chiếu đến phương thức cũ giống như một tham chiếu đến một giá trị biến cá thể cũ sẽ vẫn tham chiếu đến giá trị cũ ngay cả khi bạn gán biến dụ đó một giá trị mới. Nếu bạn muốn công văn động hơn là lưu trữ một phương pháp cụ thể, bạn muốn gửi tin nhắn thay thế. – Chuck

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