return Node.createList(nameNode, argsNode, bodyNode);
}
@Override
public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
RubyModule containingClass = context.getRubyClass();
if (containingClass == runtime.getDummy()) {
throw runtime.newTypeError("no class/module to add method");
}
String name = getName();
if (containingClass == runtime.getObject() && name == "initialize") {
runtime.getWarnings().warn(ID.REDEFINING_DANGEROUS, "redefining Object#initialize may cause infinite loop", "Object#initialize");
}
if (name == "__id__" || name == "__send__") {
runtime.getWarnings().warn(ID.REDEFINING_DANGEROUS, "redefining `" + name + "' may cause serious problem", name);
}
Visibility visibility = context.getCurrentVisibility();
if (name == "initialize" || name == "initialize_copy" || visibility == Visibility.MODULE_FUNCTION) {
visibility = Visibility.PRIVATE;
}
scope.determineModule();
// Make a nil node if no body. Notice this is not part of AST.
Node body = bodyNode == null ? new NilNode(getPosition()) : bodyNode;
DefaultMethod newMethod = new DefaultMethod(containingClass, scope,
body, (ArgsNode) argsNode,
visibility, getPosition());
containingClass.addMethod(name, newMethod);
if (context.getCurrentVisibility() == Visibility.MODULE_FUNCTION) {
containingClass.getSingletonClass().addMethod(name,
new WrapperMethod(containingClass.getSingletonClass(), newMethod, Visibility.PUBLIC));
containingClass.callMethod(context, "singleton_method_added", runtime.fastNewSymbol(name));
}
// 'class << state.self' and 'class << obj' uses defn as opposed to defs
if (containingClass.isSingleton()) {
((MetaClass) containingClass).getAttached().callMethod(context,
"singleton_method_added", runtime.fastNewSymbol(name));
} else {
containingClass.callMethod(context, "method_added", runtime.fastNewSymbol(name));
}
return runtime.getNil();
}