2

I can`t alias method "dump" from Marshal module

#include "ruby.h"
VALUE Marshal = Qnil;
void Init_test(){
  Marshal = rb_define_module("Marshal");
  rb_define_alias(Marshal, "hal_dump", "dump");//No error, but don`t work
}

In ruby:

require './test'
p Marshal.methods.grep(/dump/).sort #[:dump]

How i can do alias?

Strelokhalfer
  • 324
  • 1
  • 7

1 Answers1

4

Your C code is similar to the following Ruby code:

module Marshal
  alias hal_dump dump
end

dump is a singleton method but also a private instance method (that combination is a so-called module function). You only define an alias of the private instance method.

p Marshal.private_instance_methods.grep(/dump/) # => [:dump, :hal_dump]

That's also why you don't get an error. However you want to define an alias of the singleton method. That can be done by opening the singleton class. A corrected Ruby version might look like this:

p Marshal.methods.grep(/dump/) # => [:dump]
class << Marshal
  alias hal_dump dump
end
p Marshal.methods.grep(/dump/) # => [:dump, :hal_dump]

The MRI C API implements the rb_singleton_class() function. It returns the singleton class and can be used like this to fix your code:

rb_define_alias(rb_singleton_class(Marshal), "hal_dump", "dump");
cremno
  • 4,672
  • 1
  • 16
  • 27
  • 1
    `dump` is actually defined using `rb_define_module_function`, which defines a module (singleton) method _and_ a private instance method (otherwise you would get an error when trying to alias it). `p Marshal.private_instance_methods` should show it. – matt Aug 14 '15 at 14:32
  • @matt: Thanks, I've missed that. I'll correct my answer soon. – cremno Aug 14 '15 at 14:35