设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 3495|回复: 8
打印 上一主题 下一主题

[RMVA发布] 脚本渣でもaliasがしたくない! 2014.12.16 更新

[复制链接]

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2207
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

跳转到指定楼层
1
发表于 2014-1-26 18:47:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 taroxd 于 2014-12-16 17:45 编辑

曾经看到有人吐槽说,要是ruby有个关键字 def+ 之类的,可以直接在方法后面加东西就不用alias了。
于是闲着蛋疼写了类似的东西=。=
如果有什么bug的话求回复~

RUBY 代码复制
  1. =begin
  2.  
  3. 作者:Taroxd
  4. -------------------------------------------------------
  5. 2014/2/14 更新
  6. 修改了def系列的实现方式,不会污染名称空间
  7. def系列会同步方法的访问限制
  8. 修改了一些方法名
  9.  
  10. 2014/2/15 更新
  11. 可以使用return,并支持block参数。
  12.  
  13. 2014/2/18 更新
  14. 添加def_chain,彻底抛弃alias。
  15. def_chain可以完全替代以前的alias
  16.  
  17. 2014/4/6 更新
  18. 添加了singleton_def系列,可以用来重定义类方法等
  19.  
  20. 2014/8/27 更新
  21. def_before 与 def_after 添加了 hook 参数
  22. 对顶层环境添加了 def 系列的支持
  23.  
  24. 2014/10/08 更新
  25. 对 def_with 与 def_chain 同样添加了 hook 参数
  26.  
  27. 2014/12/16 更新
  28. 重构代码,使之更加易于扩展。
  29. 增加了 def_after!, def_and, def_or, def_if, def_unless
  30. -------------------------------------------------------
  31.  
  32. 使用示例可以参考 https://rpg.blue/forum.php?mod=forumdisplay&action=list&fid=539#groupnav
  33. 里面有大量的使用示例
  34.  
  35. ------------------------------------------------------
  36. =end
  37.  
  38. module Taroxd end
  39.  
  40. module Taroxd::Def
  41.  
  42.   # 导入
  43.   Singleton = Module.new { Object.send :include, self }
  44.   Module.send :include, self
  45.  
  46.   # 获取方法的访问限制
  47.   def get_access_control(sym)
  48.     return :public    if public_method_defined?    sym
  49.     return :protected if protected_method_defined? sym
  50.     return :private   if private_method_defined?   sym
  51.     nil
  52.   end
  53.  
  54.   template = lambda do |singleton|
  55.     if singleton
  56.       klass = 'singleton_class'
  57.       get_method = 'method'
  58.       define = 'define_singleton_method'
  59.     else
  60.       klass = 'self'
  61.       get_method = 'instance_method'
  62.       define = 'define_method'
  63.     end
  64.     %(
  65.       def <name>(sym, hook = nil, &b)
  66.         access = #{klass}.get_access_control sym
  67.         old = #{get_method} sym
  68.         if b
  69.           #{define} sym, &b
  70.           hook = #{get_method} sym
  71.         end
  72.         if hook.respond_to? :to_sym
  73.           hook = hook.to_sym
  74.           #{define} sym do |*args, &block|
  75.             <pattern_sym>
  76.           end
  77.         elsif hook.respond_to? :call
  78.           #{define} sym do |*args, &block|
  79.             <pattern_call>
  80.           end
  81.         elsif hook.kind_of? UnboundMethod
  82.           #{define} sym do |*args, &block|
  83.             <pattern_unbound>
  84.           end
  85.         end
  86.         #{klass}.send access, sym
  87.         sym
  88.       end
  89.     )
  90.   end
  91.  
  92.   # 保存模板和替换 'hook(' 字符串的字符
  93.   template = {false => template.call(false), true => template.call(true)}
  94.  
  95.   # 替换掉 pattern 中的语法
  96.   gsub_pattern = lambda do |pattern, singleton|
  97.     old = singleton ? 'old' : 'old.bind(self)'
  98.     pattern.gsub('*', '*args, &block')
  99.            .gsub(/old(\()?/) { $1 ? "#{old}.call(" : old }
  100.   end
  101.  
  102.   # 存入代替 "hook(" 的字符串
  103.   template['sym']     = '__send__(hook, '
  104.   template['call']    = 'hook.call('
  105.   template['unbound'] = 'hook.bind(self).call('
  106.  
  107.   # 获取定义方法内容的字符串
  108.   code = lambda do |name, pattern, singleton|
  109.     pattern = gsub_pattern.call(pattern, singleton)
  110.     template[singleton]
  111.       .sub('<name>', name)
  112.       .gsub(/<pattern_(\w+?)>/) { pattern.gsub('hook(', template[$1]) }
  113.   end
  114.  
  115.   main = TOPLEVEL_BINDING.eval('self')
  116.  
  117.   # 定义 def_ 系列方法的方法
  118.   define_singleton_method :def_ do |name, pattern|
  119.     name = "#{__method__}#{name}"
  120.     module_eval code.call(name, pattern, false)
  121.     Singleton.module_eval code.call("singleton_#{name}", pattern, true)
  122.     main.define_singleton_method name, &Kernel.method(name)
  123.   end
  124.  
  125.   # 实际定义 def_ 系列的方法
  126.   def_ :after,  'ret = old(*); hook(*); ret'
  127.   def_ :after!, 'old(*); hook(*)'
  128.   def_ :before, 'hook(*); old(*)'
  129.   def_ :with,   'hook(old(*), *)'
  130.   def_ :chain,  'hook(old, *)'
  131.   def_ :and,    'old(*) && hook(*)'
  132.   def_ :or,     'old(*) || hook(*)'
  133.   def_ :if,     'hook(*) && old(*)'
  134.   def_ :unless, '!hook(*) && old(*)'
  135. end

评分

参与人数 5星屑 +126 收起 理由
VIPArcher + 60
satgo1546 + 36
余烬之中 + 10
晴兰 + 10
无脑之人 + 10 精品文章

查看全部评分

Lv1.梦旅人

梦石
0
星屑
112
在线时间
551 小时
注册时间
2012-8-18
帖子
1429
2
发表于 2014-1-27 18:34:34 | 只看该作者
ruby如果有宏就好了- -可以做很多死0 0+

点评

语法糖不就是。。。  发表于 2014-1-27 21:10
我要填坑!我要背单词!我要学日语!我要每天锻炼!
好吧呵呵= =
回复 支持 反对

使用道具 举报

Lv3.寻梦者

○赛

梦石
0
星屑
1249
在线时间
1276 小时
注册时间
2013-1-22
帖子
2246

贵宾

3
发表于 2014-1-31 00:17:58 | 只看该作者
看了半天愣是没看懂用法……
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

百合控

梦石
0
星屑
6438
在线时间
1274 小时
注册时间
2013-8-21
帖子
3657

开拓者

4
发表于 2014-1-31 08:13:49 | 只看该作者
实际上我不觉得这东西有很大实用性……当做练习题吧

点评

自己就很常用啊  发表于 2014-1-31 09:42
萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2207
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

5
 楼主| 发表于 2014-2-14 16:12:20 | 只看该作者
本帖最后由 taroxd 于 2014-2-15 19:19 编辑

2014/2/14 更新
修改了def系列的实现方式,不会污染名称空间
def系列会同步方法的访问限制
修改了一些方法名

2014/2/15 更新
可以使用return,并支持block参数。
感谢http://rpg.blue/thread-350420-1-1.html提供灵感
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2207
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

6
 楼主| 发表于 2014-2-18 13:15:04 | 只看该作者
2014/2/18
更新添加def_chain,彻底抛弃alias。def_chain可以完全替代以前的alias
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2207
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

7
 楼主| 发表于 2014-8-27 17:08:56 | 只看该作者
2014/8/27 更新
def_before 与 def_after 添加了 hook 参数
对顶层环境添加了 def 系列的支持
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

无限の剣制

梦石
0
星屑
9956
在线时间
5019 小时
注册时间
2013-2-28
帖子
5030

开拓者贵宾

8
发表于 2014-10-8 12:51:15 | 只看该作者
啊,写alias写得好烦啊。(old_xxx这种别名什么的最恶心了
于是我也要开始用这个脚本了

点评

挖的一手好坟···快一年的帖子你怎么找到的···  发表于 2014-10-8 23:45
跟!  发表于 2014-10-8 17:57
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2207
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

9
 楼主| 发表于 2014-12-16 17:47:44 | 只看该作者
更新,自顶
回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-27 11:15

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表