This post originated from an RSS feed registered with Ruby Buzz
by Christopher Williams.
Original Post: Ruby Browsing in RDT 0.8.0 and a Call for Help
Feed Title: Late to the Party
Feed URL: http://cwilliams.textdriven.com/xml/rss20/feed.xml
Feed Description: Ruby. Rails. Stuff.
The biggest upcoming feature change for RDT 0.8.0 will be the addition of a Ruby Browsing Perspective.
The Ruby Browsing Perspective will give you a quick overview of the available Types within a given Ruby project, and allow you to drill down into that Type's members - methods, constants and variables.
There are some interesting challenges which I've left open in the current implementation: namespacing, open classes and globals. Hopefully our users and readers to this blog can help me out in trying to bridge those gaps as best as possible.
The initial implementation of the Browsing Perspective is essentially a port of the Java Browsing Perspective. It offers a projects view, a Types view and a Members view. Selecting a project shows all the types (classes and modules) within the project in the Types view.
Selecting a Type shows all of it's members (methods, constants, globals, variables) in the Members view. Simple enough, right?
Open Classes/Types in Ruby leave the perspective wanting, though. Since the same type can be redefined and modified in many files across a project, the type will show up multiple times in the Types view.
The closest analogy in Java relates to packages across multiple source folders or projects - different areas of the file system may map to the same package name.
We'll probably have to add a "Logical Type" to wrap and combine all instances of a particular type for the view, in the same way Java creates a "Logical Package" to combine the package's contents. The question remains what to do when the same method is defined and then redefined in another file, or even later in the same file; and how to show which file the various parts of the class came from.
Next is the issue of namespacing. This issue is actually bigger than the browsing perspective and has been bugging me for a long time. See, RDT makes heavy use of the JDT for inspiration and code in developing our plugins. Our challenege is in modifying it to make sense and fit with Ruby. In the Java world there's a pretty good strict hierarchy for their models:
If you know Java, you'll know that the source folder structure matches the package naming - and therefore the namespacing for Java code. There's no direct tie between folder structure and namespacing in Ruby. So folder structure is important for load paths and require/load, but namespacing is provided by modules (enclosing the types).
Namespacing is a large issue in developing large codebases, but in my opinion, the Ruby community doesn't place much emphasis on this aspect of the language. We could structure our plugin to try and force folders and namespacing to match and throw up errors when types defined in a foo folder aren't wrapped by a "module Foo; end" - but that seems too draconian and stiff. The Ruby language doesn't enforce that - so we probably shouldn't either.
This disconnect between folders and namespaces also makes it difficult to create a view like the JDT's Package Explorer. The best I can see us doing is offering two separate views: Our current Ruby Resources View - shwoing underlying file structure; and a Namespace View - which would structure the types by their namespace (but would muddle folder structure and files since types can be redefined in multiple files and folders don't mean a thing to namespacing).
Last are globals. I assume the best way around this is to simply add a Globals view showing all the globals defined in a given project. Globals pose a challenege only in the structuring of the internal AST based model. Do we add them as children of their enclosing element, or move them up as direct children of the project? Their scope is "global" but obviously must be defined before it really does make sense to reference them, so do we need their scoping information?
I'm leaving these issues and questions out for everyone to participate. I'd like to get a better idea of what you, the users, would prefer - and what would make most sense. Please leave your feedback and comments to help me better the project.