2017-01-09 4 views
1

Я пытаюсь сделать что-то подобное, но у меня возникли проблемы с пониманием того, как использовать внутренние элементы Ruby в моем C-коде.Как создать объект Date в расширении Ruby C?

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 («гггг-мм-дд»)

Но сначала я думаю, что мне нужно знать, как создать или создать экземпляр нового объекта класса Date в C для Ruby. Как я могу это сделать, пожалуйста?

У меня есть тест, написанный для этого кода, который делает это.

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

Выход

NoMethodError: undefined method `new' for 18709:Fixnum 
+0

Этот код эквивалентен 'Date.new.parse', который, вероятно, не то, что вы хотите. – tadman

+0

Этот код не даже компиляция, так что я хочу только новый объект Date, чтобы я мог использовать его соответствующим образом. Я искал какой-то пример, но не повезло, так что даже ссылка была бы классной. –

+0

Ну, подождите, пока она скомпилируется, но мой tes t имеет NoMethodError: undefined метод 'new 'для 18709: Fixnum –

ответ

3

rb_intern возвращает internal ID for the name "Date". То, что вы хотите, это фактический класс, связанный с этим именем, и вы можете получить, что с 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")); 
+0

Да! Это похоже на то, что я хочу. Благодаря! И вы указываете меня в правильном направлении здесь, так как я не был уверен, что делать, чтобы взглянуть на него. Еще раз спасибо. –

+0

Одно из предостережений заключается в том, что все это работало до тех пор, пока мне требуется «дата» где-то в коде Ruby, когда я вызываю этот метод. Но как только я удаляю дату lib, я получаю 'date ': uninitialized constant Date (NameError). Так что я не закончил. Цель здесь - позволить C-коду инициализировать класс Date. Любые обновления? –

+0

Хорошо, Matt теперь, как мне нужна библиотека Date в моем C-коде? Должен ли я начать новый вопрос? Мы просто посмотрим, если кто-нибудь прочтет эти комментарии, прежде чем я это сделаю. Но спасибо за ваш ответ. –

0

Да благодаря Matt теперь у меня есть:

/* 
* 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

Смежные вопросы