【发布时间】:2010-02-17 01:30:50
【问题描述】:
我已经为 building .net systems with ruby / rake 准备了一个小但不断增长的框架,我已经研究了一段时间。在这个代码库中,我有以下内容:
require 'rake/tasklib'
def assemblyinfo(name=:assemblyinfo, *args, &block)
Albacore::AssemblyInfoTask.new(name, *args, &block)
end
module Albacore
class AssemblyInfoTask < Albacore::AlbacoreTask
def execute(name)
asm = AssemblyInfo.new
asm.load_config_by_task_name(name)
call_task_block(asm)
asm.write
fail if asm.failed
end
end
end
此代码遵循的模式在框架中重复了大约 20 次。每个版本的区别在于正在创建/调用的类的名称(而不是 AssemblyInfoTask,它可能是 MSBuildTask 或 NUnitTask),以及执行方法的内容。每个任务都有自己的执行方法实现。
我一直在修复这种代码模式中的错误,每次需要修复时,我都必须重复修复 20 次。
我知道可以做一些元编程魔术,并从一个位置为我的每项任务连接这段代码......但我很难让它工作。
我的想法是我希望能够这样调用:
create_task :assemblyinfo do |name|
asm = AssemblyInfo.new
asm.load_config_by_task_name(name)
call_task_block(asm)
asm.write
fail if asm.failed
end
这将连接我需要的一切。
我需要帮助!提示、建议、愿意解决这个问题的人……我怎样才能避免一遍又一遍地重复这种代码模式?
更新:你可以在这里获得完整的源代码:http://github.com/derickbailey/Albacore/提供的代码是/lib/rake/assemblyinfotask.rb
【问题讨论】:
-
+1 使用 Github,很高兴能够浏览整个源代码。
-
为什么不把所有的类定义放到模块文件中呢?然后,元编程方法只会为您节省 1 行真正的(非“结束”)代码,同时以额外的混淆为代价。除非您需要动态定义任务,否则我只会使用 vanilla 方法。
-
。 . .当然,除非这更像是一个学习练习而不是一个完成的项目。
标签: ruby metaprogramming dry