Clay
Clay

Reputation: 1157

How to use the aspector gem to wrap class methods?

I am using the ruby aspector gem to do some code instrumentation, but I need to instrument class methods in addition to instance methods. When I run the code below, I get

Foo.bar(baz)

But I expected

Foo.bar executed with result => Foo.bar(baz)

Foo.bar(baz)

How do I get the expected result?

require 'aspector'
class Foo
  def self.bar(msg)
    "Foo.bar(#{msg})"
  end
end

class FooAspect < Aspector::Base
  around :bar, method_arg: true do |method, proxy, *args, &block|
    name = "#{self.class}.#{method}"
    result = proxy.call(*args, &block)
    warn "#{name} executed with result => #{result}"
    result
  end
end
FooAspect.apply(Foo)
puts Foo.bar("baz")

Upvotes: 0

Views: 560

Answers (1)

Alexander
Alexander

Reputation: 2568

Documentation is poor in Aspector, but you can always go to spec/functionals and try to find a solution.

About your case. Just use class_methods: true option when apply your aspect:

FooAspect.apply(Foo, class_methods: true)

Full code listing:

require 'aspector'

class Foo
  def self.bar(message)
    puts message
  end
end

class FooAspect < Aspector::Base
  around :bar, method_arg: true do |method, proxy, *args, &block|
    puts 'start'
    proxy.call(*args, &block)
    puts 'end'
  end
end

FooAspect.apply(Foo, class_methods: true)
Foo.bar('execute')
=> start
=> execute
=> end

Upvotes: 3

Related Questions