Tag: 元编程

输出ruby方法的来源

假设我用一个方法创建一个类。 class A def test puts ‘test’ end end 我想知道test里面发生了什么。 我想输出: def test puts ‘test’ end 有没有办法在字符串中输出方法的来源?

动态创建没有命名空间的类

我试图使用eval方法动态创建一个类。 除了一个小问题外它工作得很好。 正如我的代码所示,我在BrowserFactory类中创建了Browser类。 当我这样做时,Browser类有一个添加的BrowserFactory命名空间。 无论如何从没有附加BrowserFactory命名空间的字符串中评估Browser类? class BrowserFactory def self.create_browser(browser) super_class = nil case browser when ‘IE’ require ‘watir’ super_class = ‘Watir::IE’ when ‘celerity’ require ‘celerity’ super_class = ‘Celerity::Browser’ end raise StandardError.new(“Browser ‘#{browser}’ is not currentlys supported”) if super_class.nil? eval <<EOS class Browser < #{super_class} include Singleton include BrowserModification end EOS return Browser.instance end end

Nils和方法链接

我只是闯入ruby世界,我可以伸出援助之手。 假设b nil 。 我想以下代码返回nil而不是“NoMethodError:undefined method” abc(“d”).e 我尝试的第一件事就是重载NilClass的missing_method来简单地返回一个nil。 这是我想要的行为,除了我不想成为这种侵扰。 如果我可以这样做,我会喜欢它 SafeNils.abc(“d”).e 所以它就像是一种干净的方式来局部地重载NilClass的行为。 我很想听到一些想法或很多资源来挖掘这个。 只要它相当干净,我也对其他方法持开放态度。 非常感谢你。

在ruby中加载/卸载/更新类

我做了一些Ruby类动态加载/卸载/更新实验,实现了插件基础设施。 我发现了几点: 如果在没有首先卸载它的情况下加载同一类的新版本,则新版本基本上与前一版本“顶部”或“合并”。 使用先前版本创建的所有现有对象都将使其类定义“更新”。 卸载类不会影响使用此类创建的现有对象。 现有的对象可以保留任何卸载的版本。 (类不能再使用,但不能使用已创建的对象) 如果在卸载先前版本后加载新版本,则创建的新对象将是新版本。 但是,在加载新版本之前创建的旧对象不会受到影响,并且仍然是旧版本。 我的问题是,是否有一种简单的方法可以使现有的对象从旧的类版本“switch”创建到新版本(但不是旧版本和新版本的合并版本)? 在我看来,可能的方法是在卸载/加载后重新创建对象,这不适合插件(不希望它被销毁)。 更新 :我的意图是使用新版本更新现有对象,而不会将旧版本与新版本合并(例如更改参数数量或删除方法)。 卸载然后重新加载似乎是最干净的方法,尽管你必须跟踪所有这些对象并在需要时重新创建它们。 此外,昂贵的物体可能不适合重新创建。 这给我留下了第二个选项,禁止意外合并发生。 只要没有删除方法,没有方法签名改变,合并应该可以正常工作。 以下是我的测试程序: $ cat test.rb load ‘v1.rb’ puts “=> ‘v1.rb’ loaded” a1 = A.new puts “=> object a1(#{a1}) created” a1.common a1.method_v1 load ‘v2.rb’ puts ”,”=> class A updated by ‘v2.rb'” a1.common a1.method_v1 a1.method_v2 a2 = A.new puts ”,”=> object […]

使用define_method动态定义的setter方法?

我使用了很多迭代来定义模型中的便捷方法,例如: PET_NAMES.each do |pn| define_method(pn) do … … end 但我从来没能动态定义setter方法,即: def pet_name=(name) … end 像这样使用define_method: define_method(“pet_name=(name)”) do … end 有任何想法吗? 提前致谢。

Ruby Metaprogramming方法列表?

刚开始学习Ruby元编程。 看看Object.methods我得到: Object.methods => [ :allocate, :new, :superclass, :freeze, :===, :==, :, :<, :, :>=, :to_s, :included_modules, :include?, :name, :ancestors, :instance_methods, :public_instance_methods, :protected_instance_methods, :private_instance_methods, :constants, :const_get, :const_set, :const_defined?, :const_missing, :class_variables, :remove_class_variable, :class_variable_get, :class_variable_set, :class_variable_defined?, :module_exec, :class_exec, :module_eval, :class_eval, :method_defined?, :public_method_defined?, :private_method_defined?, :protected_method_defined?, :public_class_method, :private_class_method, :autoload, :autoload?, :instance_method, :public_instance_method, :nil?, :=~, :!~, :eql?, :hash, :class, :singleton_class, […]

Ruby元编程,RSpec的“应该”如何工作?

我正在阅读RSpec,我试图弄清楚RSpec的“应该”是如何实现的。 有人可以提一下这个函数的元性质是如何工作的吗? 代码位于: http://github.com/dchelimsky/rspec/blob/master/lib/spec/expectations/extensions/kernel.rb TIA, -daniel 澄清: target.should == 5 目标的价值是如何传递给“应该”的,而这又是“==”与5的对比?

Ruby中的跨领域日志记录

我正在尝试从外部向方法添加日志记录(面向方面​​的样式) class A def test puts “I’m Doing something…” end end class A # with logging! alias_method :test_orig, :test def test puts “Log Message!” test_orig end end a = A.new a.test 上面的工作没问题,只是如果我需要再次为方法做别名,它会进入无限循环。 我想要一些更像super的东西,我可以根据需要多次扩展它,并且每个扩展名都使用alias作为其父级。

alias_method和class_methods不混用?

我一直在尝试修补全局缓存模块,但我无法弄清楚为什么这不起作用。 有没有人有什么建议? 这是错误: NameError: undefined method `get’ for module `Cache’ from (irb):21:in `alias_method’ …由此代码生成: module Cache def self.get puts “original” end end module Cache def self.get_modified puts “New get” end end def peek_a_boo Cache.module_eval do # make :get_not_modified alias_method :get_not_modified, :get alias_method :get, :get_modified end Cache.get Cache.module_eval do alias_method :get, :get_not_modified end end # test […]

在rails模型中动态生成范围

我想动态生成范围。 假设我有以下型号: class Product < ActiveRecord::Base POSSIBLE_SIZES = [:small, :medium, :large] scope :small, where(size: :small) scope :medium, where(size: :medium) scope :large, where(size: :large) end 我们可以用基于POSSIBLE_SIZES常量的东西替换scope调用吗? 我想我是在违反DRY来重复它们。