2010-03-18 28 views
6

Đây là những gì tôi đang cố gắng để làm:Ruby - Có thể truyền một khối như một tham số như một khối thực tế cho một chức năng khác?

def call_block(in_class = "String", &block) 
    instance = eval("#{in_class}.new") 
    puts "instance class: #{instance.class}" 
    instance.instance_eval{ block.call } 
end 


# --- TEST EXAMPLE --- 
# This outputs "class: String" every time 
"sdlkfj".instance_eval { puts "class: #{self.class}" } 

# This will only output "class: Object" every time 
# I'm trying to get this to output "class: String" though 
call_block("String") { puts "class: #{self.class}" } 

Trên dòng mà nó nói "instance.instance_eval {block.call}", tôi đang cố gắng để tìm một cách khác để làm cho các biến thể hiện mới chạy dụ eval trên khối. Cách duy nhất tôi có thể nghĩ đến để làm cho nó làm điều đó là vượt qua instance_eval khối ban đầu, không phải là một biến hay bất cứ thứ gì, nhưng là một khối thực như trong ví dụ kiểm tra.

Bất kỳ mẹo nào?

Trả lời

8

Có. Bạn có thể chuyển khối đó sang phương pháp khác bằng cách thêm vào biến khối với ký hiệu như sau:

def foo &blk 
    # now, blk is a variable bound to a block object 
    bar &blk 
end 

Lý do bạn nhận được "class: Object" là Ruby sử dụng phạm vi từ vựng. Điều này có nghĩa là tự trong puts "class: #{self.class}" đề cập đến main, ngữ cảnh mặc định.

+0

Cái gì ??? Nó thật đơn giản? Hahaha cảm ơn! Tôi đã bị mắc kẹt trên này một ngày! :) –

+0

thuật ngữ tìm kiếm là 'tham số khối'; dễ dàng hơn trong hindsight mặc dù :) – Gishu

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