gpt4 book ai didi

ruby - 我怎样才能将这段代码转换为元编程,这样我就可以停止复制它了?

转载 作者:数据小太阳 更新时间:2023-10-29 06:54:34 25 4
gpt4 key购买 nike

我有一个用于 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

最佳答案

好的,这里有一些元编程可以做你想做的事(在 ruby​​18 或 ruby​​19 中)

def create_task(taskname, &execute_body)
taskclass = :"#{taskname}Task"
taskmethod = taskname.to_s.downcase.to_sym
# open up the metaclass for main
(class << self; self; end).class_eval do
# can't pass a default to a block parameter in ruby18
define_method(taskmethod) do |*args, &block|
# set default name if none given
args << taskmethod if args.empty?
Albacore.const_get(taskclass).new(*args, &block)
end
end
Albacore.const_set(taskclass, Class.new(Albacore::AlbacoreTask) do
define_method(:execute, &execute_body)
end)
end

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

元程序员工具箱中的关键工具是:

  • class<<self;self;end - 获取任何对象的元类,以便您可以在该对象上定义方法
  • define_method - 因此您可以使用当前局部变量定义方法

同样有用的是

  • const_set , const_get : 允许您设置/获取常量
  • class_eval : 允许您使用 def 定义方法就好像你在 class <Classname> ... end地区

关于ruby - 我怎样才能将这段代码转换为元编程,这样我就可以停止复制它了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2277735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com