Reputation: 9336
I have a method called $muffinize
and I would like to find where it can be found in my code. In other words, given the following code:
class A
def foo
$muffinize(1)
end
def bar
...
end
end
class B
def shoop
$muffinize(2)
end
def woop
...
end
end
class C
def nope
...
end
end
I would like to the result to be (written to a file):
A:foo
B:shoop
I was thinking of accomplishing this with a Regex, but I was wondering if there would be some way of accomplishing this with Ruby meta-programming (which I might be accidentally using as a buzz-word)?
Upvotes: 1
Views: 164
Reputation: 1332
Kernel.caller() will help you show the line number and method that is calling it at runtime. If you put something like puts caller(1,1)
in your muffinize function it will output those locations, but only if they are called at runtime.
If you want to do offline source analysis, you need to parse the AST (abstract syntax tree) with something like https://github.com/whitequark/parser.
Here is a quick example with ripper (built into new rubies) - this isn't strictly an AST but it's not extracting classes either
#!/usr/local/env ruby
require 'ripper'
#require 'pry'
contents = File.open('example.rb').read
code = Ripper.lex(contents)
code.each do |line|
if(line[1] == :on_ident and line[2] == "muffinize")
puts "muffinize found at line #{line.first.first}"
end
end
Upvotes: 2
Reputation: 9336
By getting a list of classes and methods via ri
, I was then able to analyze each method to retreive their source code using the method_source
gem and then searching for muffinize
. This does not rule out the possibility of muffinize
from appearing in a comment or a string, but I consider the likelihood of this happening to be small enough to ignore.
Upvotes: 0
Reputation: 369428
Ignoring the fact that your code isn't even syntactically valid, this is simply not possible.
Here's a simple example:
class A
def foo
bar
muffinize(1)
end
end
A#foo
will call Object#muffinize
if and only if bar
terminates. Which means that figuring out whether or not A#foo
calls Object#muffinize
requires to solve the Halting Problem.
Upvotes: 0