rails中的 erb代码执行原理
在rails erb
文件中嵌入ruby
代码,举个例子:
@a = 1
<div><%= @a %></div>
rails
输出的是:<div>1</div>
rails
实现是:ERB.new("<div><%= @a %></div>").result
查看erb.rb
源代码:
def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
@safe_level = safe_level
compiler = make_compiler(trim_mode)
set_eoutvar(compiler, eoutvar)
@src, @encoding, @frozen_string = *compiler.compile(str)
@filename = nil
@lineno = 0
end
def result(b=new_toplevel)
if @safe_level
proc {
$SAFE = @safe_level
eval(@src, b, (@filename || '(erb)'), @lineno)
}.call
else
eval(@src, b, (@filename || '(erb)'), @lineno)
end
end
首先初始化ERB
,然后result方法里调用eval
,取变量的值相当于:eval("@a")
都是用eval("你的ruby代码")
,执行并返回
那么<%%>
呢?
erb.rb
中通过字符串匹配来识别ruby
代码,代码如下:
ERB_STAG = %w(<%= <%# <%)
def is_erb_stag?(s)
ERB_STAG.member?(s)
end
def compile_stag(stag, out, scanner)
case stag
when PercentLine
add_put_cmd(out, content) if content.size > 0
self.content = +''
out.push(stag.to_s)
out.cr
when :cr
out.cr
when '<%', '<%=', '<%#'
scanner.stag = stag
add_put_cmd(out, content) if content.size > 0
self.content = +''
when "\n"
content << "\n"
add_put_cmd(out, content)
self.content = +''
when '<%%'
content << '<%'
else
content << stag
end
end
因为要解析erb
,erb中的代码传到ruby
中都是字符串,ERB
底层非常灵性的使用eval
解析字符串,运行ruby
代码
更多操作可以看ruby元编程