# Has a method been called?

**URL:** <https://www.ruby-forum.com/t/has-a-method-been-called/67886>\
**Category:** Ruby\
**Created:** [September 7, 2006, 5:11pm UTC](https://www.ruby-forum.com/t/has-a-method-been-called/67886 "2006-09-07T17:11:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [September 7, 2006, 5:11pm UTC](https://www.ruby-forum.com/t/has-a-method-been-called/67886/1 "2006-09-07T17:11:18Z")

</div>

Hi,  
Is it possible to find out if a method has been called except by adding  
a flag to it?

class Whatever  
@flag = 0

def method\_called  
@flag += 1  
end

def has\_method\_been\_called  
false  
return true if @flag \> 0  
end

end

Cheers

Aidy

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [September 7, 2006, 5:29pm UTC](https://www.ruby-forum.com/t/has-a-method-been-called/67886/2 "2006-09-07T17:29:22Z")

</div>

On 07/09/06, aidy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

Have a look at set\_trace\_func. It’s documented in the pickaxe book  
online at [http://www.rubycentral.com/book/ospace.html](http://www.rubycentral.com/book/ospace.html) (just scroll  
down to Tracing Your Program’s Execution). You’ll probably be  
interested in the ‘call’ events.

Farrel

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [September 7, 2006, 5:31pm UTC](https://www.ruby-forum.com/t/has-a-method-been-called/67886/3 "2006-09-07T17:31:22Z")

</div>

On 9/7/06, aidy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> def has\_method\_been\_called  
> false  
> return true if @flag \> 0  
> end
> 
> end
> 
> Cheers
> 
> Aidy

If it’s enough for you to know that off-line, you can use rcov or  
ruby-prof for that. Run rcov and see whether it’s code was visited. If  
you need to know in the runtime, that’s another story 😉

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [September 7, 2006, 5:45pm UTC](https://www.ruby-forum.com/t/has-a-method-been-called/67886/4 "2006-09-07T17:45:25Z")

</div>

On 9/7/06, Jan S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > end  
> > Aidy
> 
> If it’s enough for you to know that off-line, you can use rcov or  
> ruby-prof for that. Run rcov and see whether it’s code was visited. If  
> you need to know in the runtime, that’s another story 😉

You can also whip up a little meta programming mess (warning thrown  
together, collision causing, not thread safe code follows):

class Module

def flag\_use(sym)  
self.instance\_eval do  
define\_method “#{sym}\_called?” do  
false  
end

```
  flag_name = "use_flagged_#{sym}".to_sym
  alias_method flag_name, sym
  define_method sym do
    self.class.instance_eval do
      alias_method sym, flag_name
      define_method "#{sym}_called?" do
        true
      end
    end
    flag_name
  end
end

```

end  
end

Then…

class Foo  
def bar  
puts :bar  
end  
flag\_use :bar  
end

f = Foo.new  
p f.bar\_called?  
f.bar  
p f.bar\_called?

pth

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [September 7, 2006, 5:53pm UTC](https://www.ruby-forum.com/t/has-a-method-been-called/67886/5 "2006-09-07T17:53:25Z")

</div>

On Fri, Sep 08, 2006 at 12:23:10AM +0900, Jan S. wrote:

> > return true if @flag \> 0  
> > end
> > 
> > end
> 
> If it’s enough for you to know that off-line, you can use rcov or  
> ruby-prof for that. Run rcov and see whether it’s code was visited. If  
> you need to know in the runtime, that’s another story 😉

You can do it with rcov’s API:

RUBY\_VERSION # =\> “1.8.5”  
require ‘rcov’  
class Foo;  
def foo; 1 end  
def bar; 1 end  
end

analyzer = Rcov::CallSiteAnalyzer.new  
analyzer.run\_hooked do  
f = Foo.new  
f.foo  
end

def analyzer.executed?(selector); !!defsite(selector) end

analyzer.executed? “Foo#foo” # =\> true  
analyzer.executed? “Foo#bar” # =\> false

However, in this case I’d rather intercept the method call, record it  
and  
redispatch (standard alias\_method/module\_eval idiom, or define\_method if  
the  
redefined methods take no blocks or you’re using Ruby 1.9).
