Dominik Bathon wrote:
I don't know how to get Ripper working, but depending on what you want to do, there might be better solutions like RubyNode or ParseTree.
--snip--
It's what we currently use in FreeRIDE and I kinda like the way Ripper is used. Currently we only use it to aquire all methods/modules/classes. I guess I could look into working with a different parser but I'd prefer Ripper.
Ah okay, I thought you were trying to get Ripper running for the first time, for a new project. If you already have code then it might be easier to get Ripper working.
Anyway, here is some basic code to get methods and classes with RubyNode (it's really basic and doesn't work with nested classes, just to get you started):
Lets say we have this file:
$ cat test.rb
class A
def a
1
end
def b
2
end
end
class B
def c
3
end
end
Then this code:
require "rubynode"
require "pp"
tree = IO.read("test.rb").parse_to_nodes.transform
def statements(block_or_single_node)
if block_or_single_node.first == :block
block_or_single_node.last
else
[block_or_single_node] # only one statement
end
end
statements(tree).each { |s|
if s.first == :class
p s.last[:cpath]
statements(s.last[:body].last[:next]).each { |d|
if d.first == :defn
p d.last[:mid]
pp d.last[:defn]
end
}
end
}
outputs:
[:colon2, {:mid=>:A, :head=>false}]
:a
[:scope,
{:rval=>false,
:tbl=>nil,
:next=>
[:block, [[:args, {:cnt=>0, :opt=>false, :rest=>-1}], [:lit, {:lit=>1}]]]}]
:b
[:scope,
{:rval=>false,
:tbl=>nil,
:next=>
[:block, [[:args, {:cnt=>0, :opt=>false, :rest=>-1}], [:lit, {:lit=>2}]]]}]
[:colon2, {:mid=>:B, :head=>false}]
:c
[:scope,
{:rval=>false,
:tbl=>nil,
:next=>
[:block, [[:args, {:cnt=>0, :opt=>false, :rest=>-1}], [:lit, {:lit=>3}]]]}]
The only thing that RubyNode or ParseTree won't give you are the comments and whitespace in the code.
That's a bit of a letdown, nothing too serious. Probably easy to work around by wrapping the IO-source.
Do you have any idea as to how memory-intensive either are?
They both wrap Ruby's internal NODEs. ParseTree converts them into s-expressions (nested arrays), RubyNode's transform converts them to something similar (see above, a mix of arrays and hashes). So they use as much memory as their output needs.
If you really want to avoid the transformation to s-expressions then you can use RubyNodes directly without calling transform (see documentation), but that usually shouldn't be necessary.
And btw. if you want to get the nodes without evaling the code then you currently have to use RubyNode, ParseTree doesn't support that (yet).
Dominik
···
On Sun, 20 Aug 2006 20:37:58 +0200, Jonathan Maasland <nochoice@xs4all.nl> wrote: