0

I am attempting to write a Ruby extension in C and am having an issue calling a method of a object that is passed into the extension.

For example, I have a ruby class defined as follows:

class MyClass
  def write(message)
    ...do a write...
  end
end

The extension is defined as:

#include "ruby.h"
static VALUE _init(VALUE self, VALUE logger)
{
  switch (TYPE(logger))
  {
    case T_OBJECT:
      ID method = rb_intern("write");
      if (rb_respond_to(logger, method))
        fputs("logger responds to write\n", stderr);
      else
        fputs("logger does NOT respond to write\n", stderr);
      break;
    default:
      fputs("logger not an object\n", stderr);
  }
  return self;
}

void Init_MyExt()
{
  VALUE MyExt_class = rb_define_class("MyExt", rb_cObject);
  rb_define_method(MyExt_class, "initialize", _init, 1);
}

The ruby script doing the call looks similar to:

require 'MyExt.so'
@log = MyClass.new()
@myext = MyExt(@log)

The response I get is : "logger does NOT respond to write"

I am sure I am missing some subtle issue here, as I would have expected the logger to be able to respond to the write request.

In the back of my mind, I feel that the 'VALUE logger' parameter is only describing a pointer and not describing logger as an object with methods.

Any insights are greatly appreciated. Thanks!

jstephens
  • 1
  • 2
  • 1
    Please make sure that the code you provide actually compiles/runs and demonstrates your problem. For example there is no `rb_inter` (`rb_intern`?), there is no `rb_responds_to` (`rb_respond_to`?), there’s a `)` missing in your `if`, `fputs` takes two args (did you mean `puts`?). – matt Aug 09 '16 at 14:42
  • Apologies for the coding errors. This is a snippet from a much larger code base. I had to retype it, not being able to cut/paste. While I understand it's not compilable, I was hoping someone would spot my misunderstanding or implementation. Code has been updated. – jstephens Aug 09 '16 at 16:11
  • There are still errors in the code, but when I tidy them up it works as expected (prints “logger responds to write”), so your issue probably isn’t in the code you’ve included. – matt Aug 09 '16 at 16:43
  • Interesting. OK so I can assume that my basic understanding of how it should work is correct. I'll keep poking around. Thanks. – jstephens Aug 09 '16 at 16:52
  • matt, I updated the source code above to what I am compiling, and it does compile and run. My ruby script is as follows: – jstephens Aug 09 '16 at 17:54
  • @matt, I updated the source code above to what I am compiling, and it does compile and run. My ruby script is as follows: require_relative 'MyExt.so' class Logger def write puts "hello world" end end logger = Logger.new() logger.write myext = MyExt.new(logger) my results are: hello world Logger does not respond to write Clearly, I am missing something in the way you've tidied up. As there is no other code, I'm not sure where the disconnect is. My apolgies, not familiar with how to make the script look legible. – jstephens Aug 09 '16 at 18:01
  • nevermind.... sigh..... – jstephens Aug 09 '16 at 18:49
  • The only differences in my fixes are I needed to put braces around the first `case` (since a declaration can’t be the first thing after a case label) and I returned `Qnil` rather than `self`. I don”t think the different return will matter here. I don’t know about the declaration though, I get `error: expected expression` on that line when compiling. Perhaps a compiler difference? – matt Aug 09 '16 at 19:18
  • 1
    Whatever tool is preventing you from cutting/pasting your own code, it should be drawn, quartered, and burned at the stake. There's no excuse for a tool to be that hostile to your productivity. – Wayne Conrad Aug 11 '16 at 22:59

0 Answers0