Tag: 元编程

如何在Ruby中检索调用者上下文对象?

以下是我要简化的代码片段,以避免在每次调用时传递额外的参数。 实际上,我的用例是M是一个用户库,没有在每个方法上定义context参数。 check是一种未由用户定义的方法。 # User code module M def do_something(context) puts “Called from #{context}” context.check end module_function :do_something end # Application code class Bar def check puts “Checking from #{self}…” end end class Foo < Bar def do_stuff(scope, method) scope.send method, self end end # Executed by user Foo.new.do_stuff M, :do_something 有没有办法做同样的想法,而不通过self作为do_something方法的输入参数,以检索check方法? # User code […]

Ruby类似于nil的对象

如何在ruby中创建一个Object,它将在类似于nil的逻辑表达式中被评估为false? 我的目的是在其他对象上启用嵌套调用,其中链的一半位置通常nil ,但允许所有调用继续 – 返回我的类似nil的对象而不是nil本身。 该对象将返回自己以响应任何收到的消息,它不知道如何处理,我预计我将需要实现一些覆盖方法,如nil? 。 例如: fizz.buzz.foo.bar 如果fizz的buzz属性不可用,我会返回我的类似nil的对象,它会接受调用一直到bar返回自己。 最终,上述陈述应评估为假。 编辑: 根据以下所有优秀答案,我提出了以下建议: class NilClass attr_accessor :forgiving def method_missing(name, *args, &block) return self if @forgiving super end def forgive @forgiving = true yield if block_given? @forgiving = false end end 这允许一些卑鄙的技巧,如: nil.forgiving { hash = {} value = hash[:key].i.dont.care.that.you.dont.exist if value.nil? # great, we found […]

列表Rails控制器实例变量

我试图在控制器中列出实例变量,但想出来了 irb>HomeController.instance_variable_names => [“@visible_actions”, “@inheritable_attributes”, “@controller_path”, “@action_methods”, “@_process_action_callbacks”] 我尝试了这个动作 irb>HomeController.action(“index”).instance_variable_names => [] 那么控制器实例变量属于什么?

Ruby的方法解绑机制有什么意义?

Method#unbind UnboundMethod返回对该方法的UnboundMethod引用,该引用稍后可以使用UnboundMethod#bind绑定到另一个对象。 class Foo attr_reader :baz def initialize(baz) @baz = baz end end class Bar def initialize(baz) @baz = baz end end f = Foo.new(:test1) g = Foo.new(:test2) h = Bar.new(:test3) f.method(:baz).unbind.bind(g).call # => :test2 f.method(:baz).unbind.bind(h).call # => TypeError: bind argument must be an instance of Foo 最初,我认为这非常棒,因为我预计它的工作方式与JavaScript的Function.prototype.call() / Function.prototype.apply()类似。 但是,要将方法绑定到的对象必须属于同一个类 。 我能想到的唯一应用是,如果解除绑定方法,丢失原始实现(重新定义原始或单例类中的方法),然后重新绑定并调用它。

为什么我不能在初始化中使用attr_accessor?

我正在尝试在initialize执行一个instance_eval后跟一个attr_accessor ,我不断得到这个:“initialize’:undefined method’attr_accessor’`。 为什么这不起作用? 代码看起来像这样: class MyClass def initialize(*args) instance_eval “attr_accessor :#{sym}” end end

使用Ruby的TracePoint获取方法参数

我可以使用TracePoint API访问Ruby方法的参数: def foo(foo_arg) end trace = TracePoint.trace(:call, :c_call) do |tp| tp.disable case tp.method_id when :foo, :sub method = eval(“method(:#{tp.method_id})”, tp.binding) method.parameters.each do |p| puts “#{p.last}: #{tp.binding.local_variable_get(p.last)}” end end tp.enable end trace.enable foo(10) # => foo_arg: 10 但是,当我尝试使用ac方法调用时,我收到一个错误。 “foo”.sub(/(f)/) { $1.upcase } script.rb:20:in `method’: undefined method `sub’ for class `Object’ (NameError) from script.rb:20:in `’ from […]

元编程:如何发现对象的真实类?

我在Ruby中使用元编程开玩笑,我做了这段代码: class Class def ===(other) other.kind_of?(self) end end class FakeClass def initialize(object) methods.each {|m| eval “undef #{m}” if m.to_sym != :methods } define = proc do |m| eval(<<-END) def #{m}(*a, &b) @object.#{m}(*a, &b) rescue Object raise $!.class, $!.message.gsub("FakeClass", @object.class.to_s), $!.backtrace-[$!.backtrace[-caller.size-1]] end END end object.methods.each {|m| define[m] } def method_missing(name, *a, &b) if @object.methods.include?(name.to_s) define[name] eval […]

我什么时候应该使用“类对象”,“类模块”,“模块内核”而没有?

我是ruby元编程的新手,我看到人们在不同的地方元编程代码,比如class Object , class Module , module Kernel和“nothing”(即,在类/模块定义块之外)。 例如:我正在创建一个c_attr_accessor方法来访问类变量,我不确定在哪里放置代码,因为它适用于任何这些情况。 如何确定哪个地方更适合放置新的全球代码?

Ruby中bind / unbind方法的目的是什么?

使用Method#unbind和UnboundMethod#bind的目的是什么? 从我收集的方法来看,方法是可调用的对象,如procs和lambdas,除了方法绑定到接收器的范围: class SomeClass def a_method; puts “from SomeClass”; end end s = SomeClass.new s.a_method # => “from SomeClass” 如果我在SomeClass的上下文中或者如果我有SomeClass的对象,我可以调用a_method 。 我可以通过将方法提取为Method对象来使其成为可调用对象,但在此示例中它仍然绑定到SomeClass类的对象: m = s.method :a_method m.class # => Method m.owner # => SomeClass m.call # => “from SomeClass” 为什么我要从接收器unbind方法? 也许我可以传递它或bind它bind到一个不同的对象,给它新的上下文,也许我可以有一个完全不同的对象调用这个方法没有inheritance,但我不能做任何事情,除非我把它绑定到它的对象原始类或我将其转换为Proc对象(实际上是一个lambda,因为方法和lambda有些相似): # Module#instance_method gives me an UnboundMethod ub = SomeClass.instance_method :a_method ub.class # -> UnboundMethod […]

使用元编程来包围类中的方法

我有类的方法,这些方法在输入和退出方法时记录,如下所示: def methodName1(args) @logger.debug(“>>#{ callee }”) … @logger.debug(“<<#{ callee }”) end def methodName2(args) @logger.debug(“>>#{ callee }”) … @logger.debug(“<<#{ callee }”) end def methodName1(args) @logger.debug(“>>#{ callee }”) … @logger.debug(“<<#{ callee }”) end def methodName2(args) @logger.debug(“>>#{ callee }”) … @logger.debug(“<<#{ callee }”) end 我想知道是否有一种元编程方式用记录器调用来包围方法? 它将涉及识别我想要先包围然后围绕它们的类中的所有方法。 一个