查看: 3093|回复: 8

Block 的眞意

  [复制链接]

酱油的

梦石
0
星屑
1840
在线时间
2161 小时
注册时间
2007-12-22
回帖
3216

贵宾

发表于 2008-6-6 19:42:12 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
塊(block)
:甚麽是 Block ?
        我們經常可以看到這樣類型的語句
       |[1,2,3,4].map!{|i| i +=1 }
        其中{ }所包括的部分就是塊(Block)

:Block 的實際意義是?
        說起 block ,最先想到的自然是迭代器(Interator)。
       |[1,2,3,4].map!{|i| i +=1 }
        因此,很容易就把 Block 和迭代(Interation) 聯繫起來
        當然這個本身沒有錯誤,但是實際上使用 Block 幷不止 Interator 一家
        比如文檔路徑(Dir)當中就使用了 Block
       |Dir.open("."){|dir| p dir.to_a}
        先入爲主地,很容易認爲 Dir.open 語句也是一個 Interation
        實際上無論如何,這個 p 語句都不會執行多於一次
        而且 p Dir.open(".") 與 p dir 都會返回一個數值
        那麽 這個 Block 在這裏的意義是甚麽呢?
        我們首先理解一下 Block 的實現
        
       |def testblock(val)
       |  yield val
       |end
      
        Block 的實現與 yield 語句密不可分。
        除非方法當中含有 yield 語句,否則 Block 會被視作無效
        當方法當中有 yield 語句的時候調用方法以及 Block:
        
       |testblock("I am block"){|i| p i}
      
        結果我們在屏幕看見了 "I am block" 的語句。
        但是疑問的是,yield 這個語句是怎麽操作的呢?
        
        事實勝於雄辯。再看看以下方法:
       |def testblock(val)
       |  yield val
       |  yield val
       |end
        與上面不同的是這裏調用了兩個 yield 語句
        然後我們調用這個語句
       |testblock("I am block"){|i| p i.id}
        屏幕上顯示了兩次的 8537244 (每個程序都不一樣,這裏只是參考值)
        我們得知實例的 id 是惟一的。
        p 出兩次同樣的 id 證明我們這兩個 i 是完全一樣的
        那麽結論就是:我們調用了兩次同一個實例
        
        這說明了甚麽呢?yield 語句是關鍵。
        當我們調用 Block 的時候,系統會調用 yield 語句。
        一個方法當中的 yield 語句决定了 {|instance| method }的執行次數
        Block 當中的 instance 值是完全由方法當中的 yield 語句賦予
        實際上執行的語句就差不多是這樣子
       |  val = "I am block"
       |  i = val
       |  p i.id
       |  i = val
       |  p i.id
        如果我們把語句改寫爲這樣:
       |def testblock(val)
       |  yield val
       |  yield 1
       |end
        那麽,我們看到的大概就是這樣的執行
       |  val = "I am block"
       |  i = val
       |  p i.id
       |  i = 1
       |  p i.id
        每一次的 yield 語句都把 Block 內的 |instance|重新賦值,
        然後執行後面的 method 方法。
        
        由此可見 Block 的執行次數只跟跟方法內的 yield 語句多少産生關係
        即使帶有 Block,程序也可能只執行「一次」。
        
        這個方法被稱爲 callback
        我們利用 yield 語句截取不同的值,
        返回給 Block 當中的 instance 實例
        然後再調用 method 語句(這個過程當中,instance 或者會不被計算)
        直到 yield 語句全部被執行爲止。
        
        因此,帶有 Block 的方法內部或者是這樣被執行的:
       |def testblock(val){|instance| method }
       |  instance = val
       |  method
       |  instance = val
       |  method
       |end
        PS:以上不是可行方法,只是一個運行的示意圖
        
        而 Block 跟迭代(Interation)根本沒有必然關係

PPS:以上全部是禾西在胡扯
不做頭像做簽名,看我囧冏有神(多謝山人有情提供 )

风之塞尔达

梦石
0
星屑
50
在线时间
57 小时
注册时间
2005-10-22
回帖
2437

贵宾

发表于 2008-6-6 19:45:58 | 显示全部楼层
啊   ls好
到水区发这个
在程序里延续塞尔达的传说, 在画板上勾勒塞尔达的轮廓!!
回复

使用道具 举报

头像被屏蔽
梦石
0
星屑
50
在线时间
0 小时
注册时间
2008-2-18
回帖
1385
发表于 2008-6-6 20:01:30 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复

使用道具 举报

史上最强粉丝

梦石
0
星屑
50
在线时间
9 小时
注册时间
2007-8-20
回帖
5272

贵宾

发表于 2008-6-6 20:02:52 | 显示全部楼层
我晕了………好复杂啊。
回复

使用道具 举报

酱油的

梦石
0
星屑
1840
在线时间
2161 小时
注册时间
2007-12-22
回帖
3216

贵宾

 楼主| 发表于 2008-6-6 20:16:23 | 显示全部楼层
水區比較人氣旺盛{/hx}
而且總覺得這個比較適合發在水區...反正是否是眞的禾西也不知道
不做頭像做簽名,看我囧冏有神(多謝山人有情提供 )
回复

使用道具 举报

梦石
0
星屑
1643
在线时间
1612 小时
注册时间
2007-8-28
回帖
3184

第3届短篇游戏大赛主流游戏组冠军第1届Title华丽大赛新人奖

发表于 2009-6-12 08:00:00 | 显示全部楼层
现在各个区沦落到这个地步了。
提问区,技术区和文字区的东西都发到水区里面了。
哎{/bz}
“我推荐你一个游戏吧,avg的,剧情特感人”
“我擦,都是文字图片的游戏有啥好玩的,连个战斗都没有!”
“我推荐你一个游戏吧,rpg的,战斗也新颖”
“我擦,怎么米有作i弊器?“
”你不是喜欢战斗么?”
“不,我是剧情党!!”

继续阅读请点击
http://rpg.blue/blog-53316-10027.html
回复

使用道具 举报

头像被屏蔽
梦石
0
星屑
50
在线时间
0 小时
注册时间
2008-5-23
回帖
663
发表于 2008-6-6 21:56:15 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复

使用道具 举报

酱油的

梦石
0
星屑
1840
在线时间
2161 小时
注册时间
2007-12-22
回帖
3216

贵宾

 楼主| 发表于 2008-6-6 22:04:41 | 显示全部楼层
跟提問區差不多。甚麽樣式的帖子都有。反正一時不知道歸哪里的帖子都會嚮這兩個區裏面丟

如果覺得不合適就删了它吧
不做頭像做簽名,看我囧冏有神(多謝山人有情提供 )
回复

使用道具 举报

精灵族の天使<

梦石
0
星屑
1712
在线时间
3039 小时
注册时间
2007-3-16
回帖
33092

开拓者贵宾

发表于 2008-6-6 22:57:10 | 显示全部楼层
这个好复杂……看得我头都晕了……
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部