2008-08-23 19 views
18

Joe Van Dyk asked the Ruby mailing list:Làm thế nào để sắp xếp một lambda (Proc) trong Ruby?

Hi,

Trong Ruby, tôi đoán bạn không thể sắp xếp một đối tượng lambda/proc, phải không? Có phải là có thể bằng ngôn ngữ lisp hoặc các ngôn ngữ khác không?

Những gì tôi đã cố gắng để làm:

l = lamda { ... } 
Bj.submit "/path/to/ruby/program", :stdin => Marshal.dump(l) 

Vì vậy, tôi gửi BackgroundJob một đối tượng lambda, chứa các bối cảnh/mã cho những việc cần làm. Nhưng, đoán là không thể. Tôi đã kết thúc việc sửa đổi một đối tượng ruby ​​thông thường có chứa các hướng dẫn cho những việc cần làm sau khi chương trình chạy.

Joe

Trả lời

20

Bạn không thể marshal một Lambda hoặc Proc. Điều này là do cả hai người trong số họ được coi là đóng cửa, có nghĩa là họ đóng xung quanh bộ nhớ mà họ đã được xác định và có thể tham khảo nó. (Để sắp xếp chúng, bạn sẽ phải So sánh tất cả ký ức mà họ có thể truy cập vào thời điểm chúng được tạo ra.)

Như Gaius đã chỉ ra, bạn có thể sử dụng ruby2ruby để giữ một chuỗi của chương trình. Tức là, bạn có thể sắp xếp chuỗi ký tự đại diện cho mã ruby ​​và sau đó đánh giá lại nó sau này.

+3

ruby2ruby chỉ hoạt động trên 1.8, không có cách nào chính thức để deserialize bytecode 1,9 được nêu ra. – manveru

+0

Tôi đã thấy một số dự án sử dụng "ripper" với 1.9 trước đây ... không nhìn quá dễ dàng ... – rogerdpack

+1

Ruby2ruby đang làm việc trong MRI 1.9 một thời gian. Ripper cũng rất thú vị và nó đi kèm với MRI (từ 1.9). –

4

Nếu bạn quan tâm đến việc nhận được một phiên bản chuỗi mã Ruby bằng Ruby2Ruby, bạn có thể thích this thread.

11

bạn cũng có thể chỉ cần nhập mã của bạn như là một chuỗi:

code = %{ 
    lambda {"hello ruby code".split(" ").each{|e| puts e + "!"}} 
} 

sau đó thực hiện nó với eval

eval code 

mà sẽ trả về một lamda ruby.

sử dụng định dạng %{} thoát chuỗi, nhưng chỉ đóng trên một cú đúp chưa được so khớp. tức là bạn có thể lồng niềng răng như thế này %{ [] {} } và nó vẫn được bao quanh.

hầu hết các tô sáng cú pháp văn bản không nhận ra đây là chuỗi, do đó, vẫn hiển thị đánh dấu mã thông thường.

0

Nếu proc được xác định vào một tập tin, U có thể có được vị trí tập tin của proc sau đó serialize nó, sau đó sau khi deserialize sử dụng vị trí để lấy lại cho proc một lần nữa

proc_location_array = proc.source_location

sau deserialize:

file_name = proc_location_array [0]

LINE_NUMBER = proc_location_array [1]

proc_line_code = IO.readlines (file_name) [LINE_NUMBER - 1]

proc_hash_string = proc_line_code [proc_line_code.index ("{") .. proc_line_code.length]

proc = eval ("lambda # {proc_hash_string}")