http://www.cnblogs.com/rubylouvre/archive/2011/08/28/2112321.html
前些天写html生成器的时候用到了erb,在生成html的时候是这么一句:
html=tpl.result(binding)
binding这个变量(Kernel的一个方法 T_T)有点古怪,就搜了下。它表示了ruby的当前作用域,没有任何对外可见的成员函数,唯一的用途就是传递给eval作第二个参数。因而可以这样:
def test_binding
magic='brother Chun is PURE MAN'
return binding
end
eval "puts magic", test_binding
这样就穿越了一个作用域。
有时可以见到这样的构造函数:
a=Baby.new {
name "Makr"
father "Mike"
age 0.2
}
a.cry
好处就是好看。实现起来其实也很容易,用instance_eval:
class Baby
def initialize(&blc)
instance_eval(&blc) #here
end
def name(str=nil)
@name=str if str
@name
end
def age(num=nil)
@age=num if num
@age
end
def father(str=nil)
@father=str if str
@father
end
def cry
puts "#{name} is only #{age.to_s} year old, he wanna milk! Brother Chun is PURE MAN!"
end
end
#有重复代码?用class_eval缩短之,有点像宏了:
class Baby
def initialize(&blc)
instance_eval(&blc)
end
def Baby.my_attr(*names)
names.each{|n|
class_eval %{
def #{n}(x=nil)
@#{n}=x if x
@#{n}
end
}
}
end
my_attr :name, :father, :age
def cry
puts "#{name} is only #{age.to_s} year old, he wanna milk! Brother Chun is PURE MAN!"
end
end
a=Baby.new {
name "Makr"
father "Mike"
age 0.2
}
a.cry
这里class_eval穿越到了类的作用域,实现了动态添加函数。instance_eval也是,穿越到了实例的作用域,实现修改其内部数据。明白了它们的穿越关系,我们可以实现自己的class_eval和instance_eval——从合适的地方搞到binding就行了。
class Baby
def my_instance_eval(code)
eval code, binding
end
def Baby.my_class_eval(code='')
eval code, binding
end
end
#就这么简单。调用的时候就像这样:
class Baby
def initialize(code)
my_instance_eval(code)
end
my_attr :name, :father, :age
end
a=Baby.new %{
name "Test"
father "Orz"
age 0.2
}
刚才省略了一点,那就是class_eval和instance_eval可以接受block代替字符串。搜了下,貌似没找到eval接受block的方法,所以这顶多算是只能eval字符串的山寨class_eval。
update: 想起来ruby中lambda和proc在作用域上的小区别,也就是binding的不同了。proc直接使用原先的binding,lambda继承原先作用域创建一个新的binding。
def add_method(c, m, &b)
c.instance_eval { #在此使用class_eval是一样的效果
define_method(m, &b)
}
end
add_method(String, :greet) { "Hello, " + self }
p "world".greet # => "Hello, world"
分享到:
相关推荐
output = template.result(variables.instance_eval { binding }) puts output ``` `instance_eval`方法会将`variables`哈希转换为一个对象,使得`@title`和`@username`可以访问到其中的键值。`binding`返回当前上...
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); groovyObject.invokeMethod("sayHello", null); } } ``` 在这个例子中,我们动态地定义了一个名为DynamicGroovy的类,并调用了它的...
Groovy是一种动态、灵活的编程语言,它与Java高度兼容并常常被用于简化Java开发,尤其是在脚本编写和自动化任务中。在这个场景中,我们看到了两个主要的Groovy使用示例:通过`GroovyClassLoader`解析Groovy类和通过`...
6. **EVAL和APPLY**:这两个函数是LISP的核心,EVAL用于评估一个表达式,APPLY用于将一个函数应用于一组参数。 7. **REPL(Read-Eval-Print Loop)**:LISP环境通常提供一个交互式解释器,用户可以即时运行和测试...
5. **Binding Sources**(绑定源):除了直接的数据集和数据库,ASP.NET 2.0还支持多种数据源,如XML文件、Web服务、甚至是其他控件的输出。这极大地扩展了数据绑定的可能性。 6. **模板字段**:在GridView和...
§12.3.3 使用eval方法 88 §12.3.4 性能 88 §12.4 Hook和回调方法 89 §12.4.1 什么是Hook 89 §12.4.2 Ruby中的Hook 89 §11.4.2 回调方法 90 §12.5 跟踪程序的运行 90 §12.5.1 set_trace_func 90 §12.5.2 ...
binding.value = self.$eval(exp); }); }); }; ViewModel.prototype.$eval = function(exp) { with (this.$data) { return eval('(' + exp + ')'); } }; ``` ViewModel类负责连接数据和视图。`bind`方法遍历...
RubyGems是一个包管理系统,用于管理Ruby的第三方库(gems),简化了库的安装、管理和使用过程。 #### 三、类与对象 **3.1 类的定义** 类是对象的模板,定义了一组具有相同属性和行为的对象。 ```ruby class ...
然而,除了显示文本信息,我们有时还需要在`ListBox`中展示图像,以提高用户体验和视觉吸引力。在本文中,我们将深入探讨如何在不同的编程环境中实现`ListBox`显示图像的功能,包括Windows Forms、WPF以及Web应用中...
理解控件的生命周期和数据绑定机制(如DataBinder.Eval和BindingSource)对实现动态数据展示至关重要。 3. **状态管理**:由于HTTP协议的无状态性,ASP.NET提供了多种状态管理机制,如视图状态(ViewState)、...
- **declarative binding(声明式绑定)**:在控件的属性中直接指定数据源和字段,如BoundField、TemplateField。 - **event-driven binding(事件驱动绑定)**:通过事件处理程序进行数据绑定,如Page_Load事件。...
`Pry` 是一个替代 IRB(Interactive Ruby)的 REPL(Read-Eval-Print Loop),它提供了更多的功能和方便的上下文导航;而 `Byebug` 是一个源码级别的调试器,可以让你在代码执行时插入断点,查看变量值,甚至控制...
首先,我们有多种数据绑定表达式可供选择,如 (DataBinder.Eval)和 $ %>(DataBinder.ExpandProperties)。前者用于在服务器端执行数据绑定,后者则用于访问页面上的数据源和资源。这两种表达式极大地简化了从视图...
例如,使用Repeater或ListView控件,结合DataBinder.Eval或BindingSource组件,可以方便地实现这一功能。 此外,权限管理和用户认证也是新闻发布系统的一个重要组成部分。C#和ASP.NET提供了内置的身份验证和授权...
2. **Explicit Data Binding**(显式数据绑定):使用`Bind()`或`Eval()`表达式直接在控件的属性中绑定数据,如`("ColumnName") %>' />`。 3. **Dynamic Data Binding**(动态数据绑定):在事件处理程序中手动绑定...
7. 数据绑定技术:项目可能使用了数据绑定技术,如DataBinder.Eval或BindingSource控件,来动态地将数据库中的数据呈现到Web页面上。 8. 错误处理和日志记录:一个完善的Web应用应该具备错误处理机制,如使用Try-...
3. 数据绑定事件:如DataBound和Binding,允许在数据绑定后执行自定义操作。 五、AJAX和UpdatePanel ASP.NET AJAX扩展了服务器控件的功能,允许部分页面更新,提高用户体验。UpdatePanel控件可实现异步回发,无需...
在这个源码中,可能会使用到DataBinder.Eval或BindingSource等方法来实现数据绑定。 动态浏览数据库通常涉及到以下几个关键步骤: 1. 连接数据库:源码中可能使用ADO.NET库,通过SqlConnection类建立与数据库的...
(eval-after-load 'image+ `(when (require 'hydra nil t) (defhydra imagex-sticky-binding (global-map "C-x C-l") "Manipulating Image" ("+" imagex-sticky-zoom-in "zoom in") ("-" imagex