Ruby exposes self within a class body, and also calls certain methods (e.g. Module#included) to signal certain parsing events (e.g. including of a module). These are powerful extensibility feature, allowing new methods to be written at the meta-level (e.g. Class) and easily invoked at many places within Ruby code. This RCR provides both extensibility mechanisms uniformaly throughout the source code, with access to many other syntactic elements (methods, parameters, constants, ...).
Facilities such as attr rely on methods on Class being invoked within the text of a class fdefinition with self = current_class. I can write new methods on Class and explicitly invoke them directly from anywhere within a class that self is bound.
Similarly, methods such as Module#included and Class#inherited are always invoked by the Ruby intepreter on certain events like module inclusion or class inheritance. I can override these methods for my own module or class and they are automatically invoked when those events take place with my module or class.
However, these two facilities are limited. I cannot define new methods on Method (or UnboundMethod, or whatever the underlying meta-level class will be called) and explicitly invoke them (similar to today's common attr invocation) at appropriate points (if any) in a method definition. I cannot write new methods on Parameter ... etc.
Similarly, I cannot override methods on Method, Parameter, etc. and have them automatically invoked by Ruby at key sentinel points in the code e.g. Method#started, ParamList#finished
This makes it more awkward than necessary to extend the meta-level e.g. I may want to create and attach information to explicit "Attribute" and "Method" objects to represent various meta-data information
This facility could be extremely useful if more uniformly available. Classes representing the entire Ruby Abstract Syntax Tree should be published (Method, Parameter, Constant, ...), self should be bound to instances of these AST classes during parsing, and a rich set of events should be defined that call methods on those AST objects (Class#started, Class#finished, Module#included, Class#inherited, ParamList#started, ParamList#finished, etc.) just as SAX parsers raise events when procesing an XML stream).
The examples below are meant only to illustrate the idea. I do not have detailed enough knowledge of the Ruby grammar to know which points in the code would be reasonable choices for definition of new methods or explicit invocation of methods, or if some syntax change may be involved . I have annotatated the code with [1][2]... as points in the code that I cross-reference subsequently.
class Method [1]
def started [2]; p "New Method"; end
def explicit [3]; p "Method#explicit"; end
end
class [4] A [5]
def [6] foo [7] explicit [8] (a [9] ...)[10]
# body
end [11] def self.wrapped [12] (...) # used like self.included in a class
end [13]
[14]
end [15]
> Explanation of above code refers to [1], [2], etc.
self = the new Class hereClass#named invokedself = the new Method hereMethod#named invoked hereMethod#explicit invoked explicitly hereself = the new Param hereself = the ParamList here; ParamList#finished invokedself = the new Method object here; hence ...self.wrapped defines singleton version of predefined Method#wrappedself is still bound to the "self.wrapped" method objectself = the Class object hereself still = the Class object hereIf I knew more of how the Ruby grammar was being implemented I could probably suggest something. However, most of this seems to require a generalization of facilities currently available: self binding during parsing, and automatic invocation of pre-defined methods at key events during parsing.
Back to RCRchive.
RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog