2011-06-10 34 views
25

Tôi đang thực hiện một số phản ánh và chạy vào một khối đường bất ngờ.Phương pháp Ruby tự trả về

Có một phương pháp đối tượng trong ruby ​​(hoặc đường ray) mà trả về bản thân

ruby-1.9.2> o = Object.new 
=> #<Object:0x00000104750710> 
ruby-1.9.2> o.class 
=> Object 
ruby-1.9.2> o.send :self 
NoMethodError: undefined method `self' for #<Object:0x00000104750710> 

Những gì tôi muốn

ruby-1.9.2> o.send :self 
=> #<Object:0x00000104750710> 

Đây có phải là xây dựng trong? Hay tôi cần phải mở rộng đối tượng (Nó luôn luôn được tôi lo lắng mở cửa Object):

class Object 

    def itself 
    self 
    end 

end 

Và rồi vậy:

ruby-1.9.2> o.send :itself 
=> #<Object:0x00000104750710> 

Ok, một số nền tảng trên những gì tôi đang cố gắng để đạt được . Tôi có một helper bảng chung trong ứng dụng ray của tôi, và bạn gọi nếu như vậy:

render_list @person, [{field: :name, link_to: :itself}, 
         {field: {address: :name}, link_to: :address}] 

tôi đã đấu tranh trên đúng cách để gọi :itself - nhưng tôi nghĩ rằng bản vá của tôi là con đường để đi .

+1

Không rõ bạn đang cố gắng làm gì ở đây. 'self' không chính xác là một phương thức trong trường hợp này, theo như tôi biết, nhưng là một tham chiếu đến ngữ cảnh hiện tại. Bạn đang mong 'o.self' khác với 'o' bằng cách nào đó? – tadman

+0

Có thể mọi người có thể cung cấp câu trả lời hữu ích hơn nếu bạn đưa ra ví dụ về mục tiêu cuối cùng của bạn là gì? –

+0

@brett - đã thêm – Jonathan

Trả lời

33

Có! Nếu bạn có phiên bản Ruby 2.2.0 trở lên, bạn có thể sử dụng phương thức Kernel#itself.

Bạn có thể xem thảo luận sâu rộng về tính năng này tại đây: https://bugs.ruby-lang.org/issues/6373. Bản vá được gửi bởi Rafael França trong thông điệp số 53.

Bạn có thể xem nó trong nguồn Ruby chính thức bằng cách xem trong object.c.

+0

Có - Thật tuyệt vời! – Jonathan

+0

Ngoài ra, nếu bạn đang sử dụng Rails (hoặc chỉ Hỗ trợ Hoạt động), bạn nên có ngay cả trên các phiên bản Ruby cũ hơn. – johncip

4

self chính đối tượng, không cần phải tìm nạp thêm. Sau khi vá của bạn, hãy thử như sau:

>> a=[2,3,4] #=> [2, 3, 4] 
>> a == a.itself #=> true 
>> a.object_id #=> 71056290 
>> a.itself.object_id #=> 71056290 

... nó là hoàn toàn giống nhau

+0

Bạn chỉ có thể sử dụng "o" bất cứ khi nào bạn sử dụng "o.itself". Nói cách khác, không cần phải vá ruby. – Bira

+0

Trong thực tế, nó có ý nghĩa - '[1,2,3] .index_by (&: chính nó)', nhưng bây giờ tôi nghiêng về hướng xác định 'lambda {| * x | x} 'chỉnh sửa toàn cầu –

+0

: lambda {| x | x} –

3

self là một từ khóa đề cập đến người nhận mặc định. Nó không phải là một phương pháp. Xem this page để biết ví dụ.

Phương thức itself của bạn hoạt động tốt. Bạn cũng có thể nói:

o.instance_eval('self') 

Đối với một lớp học, sử dụng class_eval thay vì:

Object.class_eval('self') 
+6

'o .instance_eval ('self') 'là một cách khá điên rồ khi nói' o'. – tadman

+1

@tadman - đôi khi cần thiết, tức là. trong trường hợp của tôi tôi đang làm một số phản ánh nơi tôi cần chức năng này – Jonathan

5

Nếu bạn đang sử dụng của Ruby phiên bản> = 1.9, bạn có thể sử dụng tap phương pháp với khối rỗng:

Object.tap{}  => Object 
Object.new.tap{} => #<Object:0x5f41334> 
+0

gọn gàng - tôi không bao giờ biết về phương pháp này – Jonathan

+3

Thật không may là khối yêu cầu có nghĩa là bạn không thể chỉ cần đi qua một tham chiếu đến: tap một cách mù quáng, bạn phải chắc chắn để luôn luôn gọi nó bằng khối. –

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