2010-02-18 3 views
4

IronRuby를 사용하고 있고 C# 메서드가있는 블록을 사용하는 방법을 알아 내려고합니다.C# 메서드로 IronRuby 블록을 사용하는 방법

def BlockTest() 
    result = yield("hello") 
    puts result 
end 

BlockTest { |x| x + " world" } 

C# 및 아이언 루비와 같은 일을하는 나의 시도는 다음과 같습니다 :

내가 모방을 시도하고있어 기본적인 루비 코드

string scriptText = "csharp.BlockTest { |arg| arg + 'world'}\n"; 
ScriptEngine scriptEngine = Ruby.CreateEngine(); 
ScriptScope scriptScope = scriptEngine.CreateScope(); 
scriptScope.SetVariable("csharp", new BlockTestClass()); 
scriptEngine.Execute(scriptText, scriptScope); 

BlockTestClass입니다 :

public class BlockTestClass 
{ 
    public void BlockTest(Func<string, string> block) 
    { 
     Console.WriteLine(block("hello ")); 
    } 
} 

C# 코드를 실행하면 예외가 발생합니다.

나는 다음과 같은 작동에 아이언 루비 스크립트를 변경하는 경우 인수

잘못된 번호 (1 0)

.

string scriptText = "csharp.BlockTest lambda { |arg| arg + 'world'}\n"; 

그러나 나는 내 원래 루비 예의 등가의 있도록 원래 아이언 루비 스크립트로 작업하는 방법을 어떻게해야합니까?

string scriptText = "csharp.BlockTest { |arg| arg + 'world'}\n"; 

답변

2

루비의 블록은 C# 또는 다른 .Net 언어로 이해할 수있는 개념이 아닙니다.

위임자의 C#에서 비슷한 개념으로 '하나 전달'하려면 이해할 수있는 방식으로 '포장해야'합니다.

블록 밖으로 람다를 만들면 위임자 또는 표현식을 기대하는 C# 코드로 전달할 수있는 항목이됩니다.

이것은 '함수 포인터'가 델리게이트로 구현되지 않았지만 (예 : f #의 FastFunc 인스턴스) 전달 된 f #과 같은 축복 된 언어의 경우에도 'Alt.Net'커뮤니티의 일반적인 문제입니다. 이 중 하나는 C# 예제와 같은 것으로 델리게이트에 래핑해야합니다 (사실상 호출이 매개 변수를 기본 인스턴스에 전달하고 결과를 다시 반환하는 대리자를 만듭니다).

자동으로 수행하는 경우 이러한 변환이 더 좋을 것이라고 주장 할 수 있지만 복잡하고 이상한 가장자리 또는 버그가 발생할 수 있으며 많은 개발자는 코드를보고 이러한 배치 작업이 수행된다는 것을 알고 싶어합니다. . 또한 합리적인 전환 (항상 존재하는 것보다 많을 수도 있음)이 없기 때문에 사용자가 어떤 일이 일어날 지 결정하는 것이 합당한 기본입니다.

-1

당신은 C#에서 루비 블록을 완전히 사용할 수 있습니다. 사실, 현재이 프로덕션에있는 응용 프로그램에서 이것을 사용했습니다!

C#을 파일에서 : 아이언 루비에서

public void BlockTest(dynamic block) 
{ 
Console.WriteLine(block.call("world")); 
} 

:

#require the assembly 
block = Proc.new {|i| "hello " + i } 
Blah::Blah.BlockTest block 

참고 : 여기 어떻게 C# 4.0 대부분의 경우에만

+0

람다 접근법을 사용하는 것과 같은 방법입니다. Ruby가 명시 적으로 람다 또는 Proc 객체를 만들 필요없이 동일한 직관적 인 방법으로 블록을 사용하는 방법을 찾으려고했습니다. – sipwiz

1

테스트, 아이언 루비 프로세서 수와 람다는 CLR 작업, Funcs, 대리자 형식 및 동적 개체와 상호 교환 가능합니다.그러나 일부 call-site 변환 이외에 Ruby 통사론적인 설탕이 거의 없습니다. 한 번 우리는 문법을 고상하게 만들었습니다. IronRuby는 Ruby 블록을 CLR 이벤트 핸들러로 전달할 수 있습니다 : button.on_click {|s,e| ... }.

블록을 CLR 메서드로 전달할 수있는 방법은 다양했습니다. 마지막 인자가 호출 가능한 객체 인 메소드를 검출하거나 특별한 명명 된 파라미터를 허용함으로써 가능하다. 이미 기능 요청 (암호로 이름이 지정되어 있음)이 이미 열려 있습니다 : http://ironruby.codeplex.com/workitem/4511. 기꺼이 기여하고자하는 누구에게나 좋은 도전이 될 것입니다.

관련 문제