Ruby中的繫結和eval

2021-06-21 07:46:42 字數 1905 閱讀 8648

ruby是一種指令碼語言,他的每一步執行都需要乙個上下文環境,我們知道ruby的頂層環境就是main作為self,ruby的eval可以把傳入的字串當作指令碼**來解釋執行,這裡同樣需要乙個作用域。我們來看乙個實驗:

irbname = 「tony」

eval(「p name」)

=> tony

def test

name = 「hello」

endtest

=> hello

name

=> tony

這裡說明方法裡和方法外各自的作用域不同,並且方法內的區域性變數不會覆蓋外面的變數

我們再來看

def test_x

name = 「ruby」

return binding

endb = test_x

=>

eval(「name」,b)

=>ruby

好了,這裡我們看到eval輸出的是ruby而不是tony,那麼說明eval的執行上下文環境是可以通過第二個引數傳進去的,而此時,我們對方法進行了繫結,因此在這個作用域裡,name就是ruby,那麼我們接下來再去看看binging到底繫結的是什麼

irb開啟乙個新的會話視窗

class myclass

def test_bind

name = 『tony』

@name = 『tony』

b = binding

age = 23

@age = 24

return b

endend

m = myclass.new

b = m.test_bind

eval(『m.name』)

=>undefined method 『name』 for

說明在退出m的test_bind作用域後,我們無法訪問其中的區域性變數

eval(『m.@name』)

=> syntax error,因為我們不能直接訪問m.@name

eval(『name』,b)

=>tony

說明,這個繫結包含定義繫結前的區域性變數

eval(『age』,b)

=>23

說明,這個繫結包含定義在繫結後的區域性變數

eval(『@name』,b)

=>tony

說明,同樣能繫結例項變數

eval(『self』,b)

=>

說明繫結儲存了當時的self物件

eval(『self.name』,b)

undefined method 『name』 of

綜上:binding用在方法中時,不論定義在**,它都能夠儲存當前作用域(方法)和當前的self物件,以供eval方法呼叫,同樣地,在類方法也有同樣的作用

接下來,我們再來看下binding對proc等的儲存

irb開啟乙個新的會話視窗

def test_bind(x,y,&p)

p 「x:#,y:#」

p p.call x,y

return binding

endp1 = proc.new()

p2 = proc.new()

b1 = test_bind(3,5,&p1)

=>x:3,y:5

=>8

=>

b2 = test_bind(3,5,&p2)

=>x:3,y:5

=>15

=>

eval(『p.call x,y』,b1)

=>8

eval(『p.call x,y』,b2)

=>15

充分說明,binding不僅可以儲存作用域的變數和self,還能儲存作用域中的block物件

只有充分理解了ruby中的binding,才能理解很多後面的東西,也才能更好地發揮eval的作用,就先記到這裡!

ruby的動態性 eval 家族

eval 將字串作為 來求值,最直接,也是最危險的方法。編寫乙個讓別人在執行時鍵入方法名的方法 print method name m gets.chomp eval def puts hi end eval m 如果在執行時,輸入abc,那麼eval求值的字串是 def abc puts hi e...

資料繫結時Eval的使用

imageurl eval 是否啟用 tostring 啟用 images play.png images stop.png commandname beginandstop height 16px width 16px commandargument eval bt id 開始做的時候居然忘了 這...

Eval繫結多表查詢後的資料

select c.id,a.pcname,b.pcname,b.pinyin,b.jianma,c.location from cf provice city a inner join cf provice city b on a.pcid b.parentid inner join cf loca...