如何在 Ruby C 扩展中创建 Date 对象



我正在尝试做这样的事情,但我无法理解如何在 C 代码中使用 Ruby 内部。

static VALUE func_get_date_object(VALUE self, VALUE vdate){
VALUE rb_date;
VALUE date;
rb_date = rb_funcall(rb_intern("Date"), rb_intern("new"), 0);;
date = rb_funcall(rb_date, rb_intern("parse"), 0);
return date;
}

我想做的是将 vdate 作为字符串传入,就像您对 Date.parse('yyyy-mm-dd') 所做的那样

但首先我认为我需要知道如何在 C 中为 Ruby 创建或实例化一个新的 Date 类对象。请问我该怎么做?

我有一个为该代码编写的测试来执行此操作。

def test_date
  assert_equal('', @t.date(@t_date_str))
end

输出为

NoMethodError: undefined method `new' for 18709:Fixnum

rb_intern返回名称"Date"的内部ID。你想要的是与此名称关联的实际类,你可以通过rb_const_get得到它:

VALUE cDate = rb_const_get(rb_cObject, rb_intern("Date"));

然后,您可以将它与 rb_funcall 一起使用来创建 Date 类的新实例:

rb_date = rb_funcall(cDate, rb_intern("new"), 0);

由于看起来您实际上想要调用 Date.parse 类方法,因此您可能希望直接在类上调用parse

VALUE parsed = rb_funcall(cDate, rb_intern("parse"), 1, rb_str_new_cstr("2017-1-9"));

是的,多亏了马特,我现在有:

/*
* call-seq:
*  date('yyyy-mm-dd')
*
* convert input string to Date object.
*
*/
static VALUE func_get_date(VALUE self, VALUE vdate){
  VALUE cDate = rb_const_get(rb_cObject, rb_intern("Date"));
  VALUE parsed = rb_funcall(cDate, rb_intern("parse"), 1, vdate);
  return parsed;
}

测试是:

class TestCalcSun300 < Test::Unit::TestCase # MiniTest::Test
  def setup
    @t = CalcSun.new
    @t_date_str = '2000-01-01'
    @t_date = Date.parse('2000-01-01')
  end
  def test_date
    assert_equal(@t_date, @t.date(@t_date_str))
  end
end

只要我在 Ruby 代码中需要"日期"就可以很好地工作。但是没有它,我没有初始化任何Date类。:-(哦,好吧,我在学习。

这是针对仍在开发中的 Ruby 宝石,但我会分享它,以防有人想玩它。原始宝石很好,但它没有所有最新功能。名称在 rubygems.org 上相同

calc_sun

最新更新