문제

조 반 다이크 Ruby 메일링 리스트에 질문했습니다.:

안녕,

Ruby에서는 람다/proc 개체를 마샬링할 수 없는 것 같습니다. 그렇죠?LISP 또는 다른 언어로 가능합니까?

내가 하려고 했던 것:

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

그래서 저는 BackgroundJob에 Lambda 객체를 보내고 있습니다. 여기에는해야 할 일에 대한 컨텍스트/코드가 포함되어 있습니다.하지만, 그건 불가능했을 것 같아요.나는 프로그램이 실행 된 후해야 할 일에 대한 지침이 포함 된 일반 루비 객체를 마샬링했습니다.

도움이 되었습니까?

해결책

Lambda 또는 Proc을 마샬링할 수 없습니다.이는 둘 다 클로저로 간주되기 때문입니다. 즉, 정의된 메모리 주변을 닫고 이를 참조할 수 있다는 의미입니다.(마샬링하려면 생성 당시 액세스할 수 있는 모든 메모리를 마샬링해야 합니다.)

Gaius가 지적했듯이 다음을 사용할 수 있습니다. 루비2루비 프로그램의 문자열을 얻으려면.즉, 루비 코드를 나타내는 문자열을 마샬링한 다음 나중에 다시 평가할 수 있습니다.

다른 팁

코드를 문자열로 입력할 수도 있습니다.

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

그런 다음 eval로 실행하십시오.

eval code

그러면 루비 람다가 반환됩니다.

사용하여 %{} format은 문자열을 이스케이프하지만 일치하지 않는 중괄호에서만 닫힙니다.즉.이렇게 중괄호를 중첩할 수 있습니다 %{ [] {} } 그리고 그것은 여전히 ​​​​동봉되어 있습니다.

대부분의 텍스트 구문 강조 표시기는 이것이 문자열임을 인식하지 못하므로 여전히 일반 코드 강조 표시를 표시합니다.

Ruby2Ruby를 사용하여 문자열 버전의 Ruby 코드를 얻는 데 관심이 있다면 다음을 참조하세요. 이 스레드.

노력하다 루비2루비

나는 proc_to_ast가 최고의 작업을 수행한다는 것을 알았습니다. https://github.com/joker1007/proc_to_ast.

Ruby 2+에서는 확실히 작동하며 Ruby 1.9.3+ 호환성에 대한 PR을 만들었습니다(https://github.com/joker1007/proc_to_ast/pull/3)

proc이 파일에 정의된 경우 U는 proc의 파일 위치를 가져온 다음 직렬화한 다음 역직렬화한 후 위치를 사용하여 proc로 다시 돌아갈 수 있습니다.

proc_location_array = proc.source_location

역직렬화 후:

파일 이름 = proc_location_array[0]

line_number = proc_location_array[1]

proc_line_code = IO.readlines(파일_이름)[line_number - 1]

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

proc = eval("람다 #{proc_hash_string}")

옛날에는 Ruby-Internal gem(https://github.com/cout/ruby-internal), 예:

p = proc { 1 + 1 }    #=> #<Proc>
s = Marshal.dump(p)   #=> #<String>
u = Marshal.load(s)   #=> #<UnboundProc>
p2 = u.bind(binding)  #=> #<Proc>
p2.call()             #=> 2

몇 가지 주의사항이 있지만, 수년이 지났기 때문에 자세한 내용은 기억나지 않습니다.예를 들어 변수가 덤프되는 바인딩의 dynvar이고 다시 바인딩되는 바인딩의 로컬인 경우 어떤 일이 발생하는지 잘 모르겠습니다.AST(MRI에서) 또는 바이트코드(YARV에서)를 직렬화하는 것은 간단하지 않습니다.

위 코드는 YARV(최대 1.9.3) 및 MRI(최대 1.8.7)에서 작동합니다.약간의 노력만으로 Ruby 2.x에서 작동하지 못할 이유가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top