Dlr

1,322 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,322
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
6
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Dlr

  1. 1. Exploring DLR 江嘉诚 2011.8.28
  2. 2. 关于我• 江嘉诚 (无厚之刃)• 华南理工大学• 微博:@以无厚入有间 ( 典故参见《庄子》)• 博客:http://sharp-blade.tuita.com/
  3. 3. DLR是• Dynamic Language Runtime• 由 IronPython 发起人Jim Hugunin开发• 一个构建在CLR之上的运行时• 在.Net上构建动态语言的标准体系The DLRs mission is to enable an ecosystem ofdynamic languages on .NET.
  4. 4. 动态语言需要什么• Lexer & Parser• 交互式脚本引擎(REPL)• 动态加载代码的能力• 动态类型• 元编程(自省/魔术方法/动态修改类型)• 其它:Stackless/Actor/Continuation
  5. 5. DLR提供了什么• 脚本语言引擎• 可以在运行时编译的表达式树• 延迟绑定• 动态语言的互操作性
  6. 6. ExpressionTree
  7. 7. ExpressionTree : Hello WorldConsole.WriteLine(“Hello World”);using System.Linq.Expressions;MethodInfo method = typeof (Console) .GetMethod( "WriteLine", new Type[] { typeof(string) } );Expression call = Expression.Call(null, method, Expression.Constant("Hello World")) ;Action callDelegate = Expression.Lambda<Action>(call).Compile();callDelegate();
  8. 8. ExpressionTree : Binary Expression3+5BinaryExpression add = Expression.Add(Expression.Constant(3), Expression.Constant(5));Func<int> addDelegate = Expression.Lambda<Func<int>>(add).Compile();Console.WriteLine("{0}", addDelegate());
  9. 9. ExpressionTree : Index Expressionint[] list = { 1, 2, 3 };list [1] = 4;int[] list = { 1, 2, 3 };IndexExpression index = Expression.ArrayAccess( Expression.Constant(list), Expression.Constant(1));Expression indexAccess = Expression.Assign(index, Expression.Constant(4));Action indexAccessDelegate = Expression.Lambda<Action>(indexAccess).Compile();indexAccessDelegate();
  10. 10. ExpressionTree : IfThenElse Expressionif (true) Console.WriteLine("true");else Console.WriteLine("false");Expression ifExpression = Expression.IfThenElse( Expression.Constant(true), Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), Expression.Constant("true")), Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), Expression.Constant("false")));Action ifDelegate = Expression.Lambda<Action>(ifExpression).Compile();ifDelegate();
  11. 11. ExpressionTree : LambdaExpressionFunc<int, int, int> add = (x, y) => { return x + y; };int result = add(3, 5);Console.WriteLine("result is {0}", result);ParameterExpression x = Expression.Parameter(typeof(int), "x");ParameterExpression y = Expression.Parameter(typeof(int), "y");Expression<Func<int, int, int>> add = Expression .Lambda<Func<int, int, int>>(Expression.Add(x, y), x, y);int result = add.Compile()(3, 5);Console.WriteLine("result is {0}", result);
  12. 12. 代码即数据数据即代码
  13. 13. Dynamic & Late BindingFoo foo = new Foo();foo.act();dynamic foo = …… // new Foo()foo.act();
  14. 14. Dynamic语法的绑定过程dynamic num = 5;int result = num + 2;CallSite<Func<CallSite, object, int>> Site1;CallSite<Func<CallSite, object, int, object>> Site2;object num = 5;if (Site1 == null){ Site1 = CallSite<Func<CallSite, object, int>> .Create( Binder.Convert( CSharpBinderFlags.None, typeof(int), typeof(Program)));}
  15. 15. Dynamic & Late BindingFunc<CallSite, object, int> convert = Site1.Target;CallSite add = Site1;if (Site2 == null){ Site2 = CallSite<Func<CallSite, object, int, object>> .Create( Microsoft.CSharp.RuntimeBinder.Binder.BinaryOperation( CSharpBinderFlags.None, ExpressionType.Add, typeof(Program), ...));}int result = convert(add, Site2.Target(Site2, num, 2));
  16. 16. Dynamic语法的绑定过程dynamic num = 5;int result = num + 2;CallSite<Func<CallSite, object, int>> Site1;CallSite<Func<CallSite, object, int, object>> Site2;object num = 5;if (Site1 == null) { Site1 = CallSite<Func<CallSite, object, int>> .Create( Binder.Convert( CSharpBinderFlags.None, typeof(int), typeof(Program)));}
  17. 17. Dynamic & Late BindingFunc<CallSite, object, int> convert = Site1.Target;if (Site2 == null){ Site2 = CallSite<Func<CallSite, object, int, object>> .Create( Binder.BinaryOperation( CSharpBinderFlags.None, ExpressionType.Add, typeof(Program), ...));}int result = convert(Site1, Site2.Target(Site2, num, 2));
  18. 18. 绑定中发生了什么?• 绑定主要由Binder完成• 绑定在不同语言中是不同的,这里C#编译器使用了自己的 Binder• 绑定是昂贵的,结果会被缓存起来• Target(L0) => CallSite(L1) =>Binder (L2)• 动态类型的对象可以实现自己的绑定行为• 这种动态行为通过实现IDynamicMetaObjectProvider来 告诉编译器• 通常可以使用DynamicObject和ExpandoObject
  19. 19. ExpandoObjectdynamic any = new ExpandoObject();any.prop = 100;any.prop = "hello";any.action = new Func<int>(() => { return 99 + 1; });Console.WriteLine(any.action());foreach (var member in (IDictionary<String, Object>)any){ Console.WriteLine(member.Key + ": " + member.Value);}
  20. 20. ExpandoObject((INotifyPropertyChanged) any).PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) { Console.WriteLine("属性{0} 已更改", .PropertyName); };any.name = "某";any.age = 30;any.email = "xxx@gmail.com";
  21. 21. Method Missingusers.getByMail(“john@gmail.com”)自动从用户表中找到Mail为john@gmail.com的用户在C#中通过继承DynamicObject,并override其方法来实现具体行为。• TryGetMember • TryUnaryOperation• TrySetMember • TryGetIndex• TryDeleteMember • TrySetIndex• TryInvokeMember • TryDeleteIndex• TryConvert• TryCreateInstance • GetDynamicMemberNames• TryInvoke• TryBinaryOperation
  22. 22. Method Missing public class AnyDynamicObject : DynamicObject{ public override bool TryGetMember(GetMemberBinder binder, out objectresult) { Console.WriteLine("Shit happens,{0}属性被调用了", binder.Name); result = "no value"; return true; } public override bool TrySetMember(SetMemberBinder binder, object value) { Console.WriteLine("Shit happens,{0}属性被赋值了", binder.Name); return true; } }
  23. 23. Method Missingdynamic any = new AnyDynamicObject();Console.WriteLine(any.name);any.age = 100; Shit happens,name属性被调用了 no value Shit happens,age属性被赋值了
  24. 24. 调用Python引擎example.py : 引用:def addPrice(x, y): IronPython.dll return x + y IronPython.Modules.dll Microsoft.Dynamic.dllclass User(object): Microsoft.Scripting.dll def __init__(self, name, email): self.Name = name self.AEmail = email def say(self): print "hello"bob = User("bob", "x@gmail.com")
  25. 25. 调用Python引擎 ScriptEngine pyEngine = IronPython.Hosting.Python.CreateEngine();ScriptScope scope = pyEngine.ExecuteFile("example.py");Func<dynamic, dynamic, int> add = scope.GetVariable("add");Console.WriteLine(add(2,5));dynamic bob = scope.GetVariable("bob");Console.WriteLine(bob.Name);bob.say();7bobhello
  26. 26. 为什么Dynamic不能拯救世界
  27. 27. 谁真正需要Dynamic/DLR• 轻量级ORM• MSBuild• 模板引擎• 解释器/表达式引擎• 编译正则表达式• 调用COM• 替代Reflection.Emit的其它场合• 构建DSL (Antlr + DLR)
  28. 28. ReferenceIronPython & IronRuby:https://github.com/IronLanguages利用DLR + Antlr快速构建DSL:DLR - Build Your Own Language (without tears)利用IronRuby开发WPF应用:http://www.infoq.com/cn/articles/ironruby-wpfIron语言相关书籍:IronPython in ActionIronRuby UnleashedGraph#演示工具:http://graphsharp.codeplex.com/
  29. 29. ReferenceIronJS:https://github.com/fholm/IronJSDLR应用案例:https://github.com/IronLanguages/main/wiki/IronLanguage-usages浏览器中体验IronPython编程:http://www.trypython.org/浏览器中使用Python代替Javascript:http://visitmix.com/labs/gestalt/

×