最近在学习ror,请问ror如何实现动态访问类的全部实例变量并传递给erb页面访问的?
在struts2中好理解,因为有getter,setter和反射,那么ruby里的instance var 默认是private,而且我没有设定访问器
难道是动态添加方法,在new的时候生成一个处理template的code block?我还在学习中,能不能先点拨一下?
[b]问题补充:[/b]
请问这个过程是如何实现的?
[b]问题补充:[/b]
首先谢谢你的热心,但是你并没有回答我的问题,我的问题不是能不能或者在rails中怎么用,而是为什么可以这样用,这样用的实现的原理是什么。因为类实例变量默认是私有的,ruby是怎样动态获取到这些值并传递给view的,或者它的反射可以直接访问私有变量?不知道我说明白没有。
呵呵,这个问题很简单:
假设这个controller的实例是c
假设ERB运行的binding(运行环境)对象为o(这个o一般都是从一个白白净净的Object.new开始的)
magic就在下面的三个方法之中:
c.instance_variables
得到所有实例变量的名称,为一数组
c.instance_variable_get :@var1
得到实例变量@var1的值
o.instance_variable_set :@var1, '12'
设置o的实例变量@var1 = '12'
可能我们还需要设置一些局部变量:
o.instance_eval 'a=1'
最后渲染:
ERB.result(o.__send__ :binding)
因为binding函数是私有的,所以用__send__调用得到o的binding
只要controller中有class variable,即@some_variable,都可以傳給erb。
controller內
class CarsController < ActiveRecord::Base
def index
@cars = Car.find(:all)
.......
end
def ....
end
view內, index.html.erb
<% @cars.each do |car|%>
<%= car.name %>
<% end %>
由此controller的class variable @cars會自動傳到erb template之內。
因為template是由controller method內render call來。
而Ruby語言內有很多reflection的工具,取得各object/class內狀態,亦可以一段string轉化成object一部份。
簡單來說,ERB本身就有由ERB處load入template作parsing,evaluate template內instance variable(之前寫錯class_variable),再轉出result。
再深入就不是5分問題吧。