麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Ruby > 正文

詳解Ruby中的instance_eval方法及其與class_eval的對比

2020-10-29 19:35:31
字體:
來源:轉載
供稿:網友

instance_eval方法

這個BasicObject#instance_eval有點類似JS中的bind方法,不同的時,bind是將this傳入到對象中,而instance_eval則是將代碼塊(上下文探針Context Probe)傳入到指定的對象中,一個是傳對象,一個是傳執行體。通過這種方式就可以在instance_eval中的代碼塊里訪問到調用者對象中的變量。

示例代碼

class MyClass  def initialize    @v = 1  endendobj = MyClass.newobj.instance_eval do  self  #=> #<MyClass:0x33333 @v=1>  @v   #=> 1 endv = 2obj.instance_eval { @v = v }obj.instance_eval { @v }  # => 2

此外,instance_eval方法還有一個雙胞胎兄弟:instance_exec方法。相比前者后者更加靈活,允許對代碼塊傳入參數。

示例代碼

class C  def initialize    @x = 1  endendclass D  def twisted_method    @y = 2    #C.new.instance_eval { “@x: #{@x}, @y>: #{y}” }    C.new.instance_exec(@y) { |y| “@x: #{@x}, @y: #{y}” }  endend#D.new.twisted_method  # => “@x: 1, @y: ”D.new.twisted_method  # => “@x: 1, @y: 2”

因為調用instance_eval后,將調用者作為了當前的self,所以作用域更換到了class C中,之前的作用域就不生效了。這時如果還想訪問到之前@y變量,就需要通過參數打包上@y一起隨instance_eval轉義,但因為instance_eval不能攜帶參數,所以使用其同胞兄弟instance_exec方法。


instance_eval 與 class_eval 的區別
###instance_eval
首先從名字可以得到的信息是,instance_eval的調用者receiver必須是一個實例instance,而在instance_eval block的內部,self即為receiver實例本身。

obj_instance.instance_eval do self # => obj_instance # current class => obj_instance's singleton classend<!--more-->

根據這個定義,如果在一個實例上調用了instance_eval,就可以在其中定義該實例的單態函數 singleton_method

class Aenda = A.newa.instance_eval do self # => a # current class => a's singleton class def method1  puts 'this is a singleton method of instance a' endenda.method1#=> this is a singleton method of instance ab = A.newb.method1#=>NoMethodError: undefined method `method1' for #<A:0x10043ff70>

同樣,因為類class本身也是Class類的一個實例,instance_eval也可以用在類上,這個時候就可以在其中定義該類的singleton_method,即為該類的類函數。

換句話說,可以用instance_eval來定義類函數class method,這比較容易混淆,需要搞清楚。

class AendA.instance_eval do self # => A # current class => A's singleton class def method1  puts 'this is a singleton method of class A' endendA.method1#=> this is a singleton method of class Aclass_eval

###class_eval

再來看class_eval,首先從名字可以得到的信息是,class_eval的調用者receiver必須是一個類,而在class_eval block的內部,self即為receiver類本身。

class AendA.class_eval do self # => A # current class => Aend

根據這個定義,如果在一個類上調用了class_eval,就可以在其中定義該類的實例函數 instance_method

class Aenda = A.newa.method1#=> NoMethodError: undefined method `method1' for #<A:0x10043ff70>A.class_eval do self # => A # current class => A def method1  puts 'this is a instance method of class A' endenda.method1#=> this is a instance method of class A

換句話說,可以用class_eval來定義實例函數instance method,這也比較容易混淆,需要搞清楚。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产在线播放一区二区 | 牛牛热这里只有精品 | xxxx hd video 69| 一级黄色免费观看 | 久久99国产精品免费网站 | 91热久久免费频精品黑人99 | 91精品国产综合久久久动漫日韩 | 免费看成年人视频在线 | free japan xxxxhdsex69 | 国产精品99免费视频 | 久久免费视频一区二区三区 | 杏美月av | 国产午夜精品在线 | 九九视频久久 | 免费视频xxxx| 九一成人| 精品久久久久久久久久久久久久久久久久久 | 久久久一区二区三区四区 | 久久亚洲精选 | 成人富二代短视频 | 91精品国产91久久久久久吃药 | 久久国产精品一区 | 国产成年人视频 | 在线高清中文字幕 | 亚洲卡通动漫在线观看 | 欧美精品久久久久久久久老牛影院 | 国产精品久久久久影院老司 | 欧美3p激情一区二区三区猛视频 | 久久一级 | 一级在线| free国产hd老熟bbw | 国产亚洲精品综合一区91 | 精品国产一区二区三区久久久蜜 | 久久亚洲精选 | 一夜新娘第三季免费观看 | 久久亚洲一区二区三区成人国产 | 国产精品久久久久久影院8一贰佰 | 在线观看免费精品 | 久久艹国产精品 | 久草最新网址 | 亚洲影视中文字幕 |