Desgin Perl 6: S06-Subroutines

原文Subroutines

标题


概要 6: 子例程

版本


创建于: 2003 年 5 月 21

上一次更新: 2015 年 10 月 16

版本: 169

该文档总结了概要 6, 其中涵盖了子例程和新的类型系统。

子例程和其它 code 对象


Routine 是所有以关键字声明的 code blocks 的父类型。所有的 routines(程序)生来就带有未定义的 $_$!$/ 值, 除非该 routine 显式地声明了它们。一个编译单元, 例如模块文件或 EVAL 字符串, 也被看作是 routine, 要不然你就不能引用它们里面的 $!$/

使用 -> 声明或使用裸花括号的非-routine 的 code Blocks, 生来只有 $_, 它被别名到它的 OUTER::<$_> 上, 除非被绑定为参数。 block 通常使用由最里面的闭合 routine 所定义的 $!$/, 除非在 block 中显式地声明了 $!$/

形实转换程序是一段不会立即执行的代码, 例如因为它是条件操作符的一部分, 或者它是某个属性的默认初始化函数。它没有自己的作用域, 所以在形实转换程序中定义的任何新的变量, 都会漏到它们所在的作用域中。然而, 要知道任意和所有的 lazy(惰性)结构, 不管是基于 block 的还是基于形实转换程序的, 例如 gather 或者 start 或者 ==> 应该声明它们自己的 $/$! , 以至于那些变量的用户值不会发生异步碰撞(clobbered asynchronously)。

Subroutines (关键字: sub) 是带有参数列表的非继承程序。

Methods (关键字: method) 是有关联对象(即它们的调用者)的可继承程序并且属于特殊的类别或类。

Submethods (关键字: submethod) 是非继承方法, 或者是伪装成方法的子例程。它们拥有一个调用者并属于特殊的类别或类。

Regexes (关键字: regex)是执行模式匹配的方法(grammar 的)。它们关联的 block 拥有特殊的语法(查看 Synopsis 5)。(我们也使用术语 regex 用于传统形式的匿名模式。)

Tokens (关键字: token) 是执行低级别(low-level) 非回溯(默认的)模式匹配的 regexes。

Rules (关键字: rule) 是执行非回溯(默认的)模式匹配(而且 rules 中空白是开启的)的 regexes。

Macros (关键字: macro 或 slang) 是被安装的程序或方法, 它们作为编译程序的一部分被调用, 因此能临时取得随后编译的控制权以像编译器作弊那样作弊。

Routine 修饰符


S06-multi/value-based.t lines 7–104
S06-multi/type-based.t lines 50–57
S06-multi/type-based.t lines 58–283
S06-multi/syntax.t lines 7–183

Multis (关键字: multi) 是可以拥有多个共享同一个名字的变体的 routines, 它们通过元数、类型或其它约束被选择。

Prototypes (关键字: proto) 指定了在 proto 声明的作用域中, 那个名字的所有 muitis 所共享的共性(例如参数名, 不变性和结合性)。理论上讲, proto 是包裹在 multis 分发周围的通用包装器(wrapper)。对于每个需要一个不同候选者列表的作用域, 每个 proto 被具体化到一个实际的分发器(dispatcher)。

Only (关键字: only) 不和其它 routines 共享它们的短名字的 routines。这对所有的 routines 是默认的修饰符, 除非作用域中已经有了一个同名的 proto。(对于 subs, 执政的那个 proto 必须已经在同一个文件中声明过, 所以 从设置中或其它模块中声明的 proto 没有这种效果, 除非被显式地导入。)

在具名 routine 中, 修饰符关键字可以出现在 routine 关键字前面:

only     sub foo  {...}
proto    sub foo  {...}
dispatch sub foo  {...} # 内部的
multi    sub foo  {...}

only     method bar  {...}
proto    method bar  {...}
dispatch method bar  {...} # 内部的
multi    method bar  {...}

如果 routine 关键字被省略了, 那么就默认为 sub

修饰符关键字不能应用到匿名 routines 上。

proto 是一个通用的分发器, 其中带有唯一候选者列表的任意给定作用域会被实例化到某个分发子例程中。因此 proto从来不会被直接调用, 这和 role 不能用作实例化对象很像。

当你调用任何可能拥有多个候选者的子例程(或者方法, 或者 rule)时, 基础分发器真正调用的是 only sub 或方法 — 但是如果有多个候选者, 将被找到的 "only" 就是一个分发器。这个实例化的分发器总是被首先调用(至少在理论上 — 这通常会被优化掉)。本质上, dispatch 总是像 only sub 那样, 但是 dispatch 自身可以代理给任何它所管理的候选者。

首先为所有的候选者审查参数是分发器(dispatch)的责任。任何不能成功约束为分发器签名的调用都会立即失败。(它的签名是属于该 proto 所实例化的候选者签名的拷贝。) 然而, 该分发器(dispatch)没有必要把原来的捕获(capture)发送给它的候选者。在分发器签名中约束为位置的具名参数对于所有随后的它所管理的 multis 的调用都会变成位置的。

然后, 该分发器(dispatch)从调用者或对象的角度考虑它所管理的候选者列表, 把它们按照某种顺序排序, 然后根据每个不同的调度器(dispatchers)定义的多重分派的规则来分派它们。在 multi subs 的情况下, 候选者列表在编译时是被知晓的。在 multi methods 的情况下, 在运行时生成(或重新生成)候选者列表可能是必要的, 根据关于继承树时所知道的。

这种默认的分发器行为在原来的 proto 中通过一个含有单个 * (即 "whatever")的 block 使用符号给表现了。因此, 标准的 proto 会仅仅有一个 {*} 主体。

proto method bar {*}

(我们不使用 … 代替它是因为它会在运行时失败, 而该 proto 实例化的 dispatch blocks 不是 stubs, 但是想要被执行。)

其它语句可以插入在 {*} 语句之前和之后以在 multi dispatch 之前或之后捕获控制:

proto foo ($a, $b) { say "Called with $a, $b"; {*}; say "Returning"; }

(那个 proto 只对带有副作用并不返回值的 multis 很有用, 因为它返回了 say 的结果, 这可能不是你想要的。查看下面的来修复它 。)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容