在ruby中将值从符号转换为字符串

时间:2016-05-09 23:07:54

标签: c ruby

我正在写一个宝石,其中一个难点是我的camelize方法。我开始用C重写它,并且它正在使用以下实现:

#include <ctype.h>
#include <ruby.h>

VALUE MyGem = Qnil;
VALUE Utils = Qnil;

VALUE camelize(VALUE self, VALUE str)
{
  char *orig_str = rb_string_value_cstr(&str);
  char new_str[strlen(orig_str)];

  char prev;
  int orig_idx = 0, new_idx = 0;

  new_str[0] = toupper(orig_str[0]);
  for (orig_idx = 1, new_idx = 1; orig_str[orig_idx] != '\0'; orig_idx++) {
    if (prev == '_') {
      new_str[new_idx++] = toupper(orig_str[orig_idx]);
    }
    else if (orig_str[orig_idx] != '_') {
      new_str[new_idx++] = orig_str[orig_idx];
    }
    prev = orig_str[orig_idx];
  }

  return rb_str_new(new_str, new_idx);
}

void Init_my_gem()
{
  MyGem = rb_define_module("MyGem");
  Utils = rb_define_module_under(MyGem, "Utils");
  rb_define_singleton_method(Utils, "camelize", camelize, 1);
}

唯一的问题是,VALUE str可以是符号或字符串。有人知道如何将str值转换为字符串,然后再将其转换为char*吗?

1 个答案:

答案 0 :(得分:2)

最简单的方法是在to_s上致电strrb_string_value_cstr将尝试使用to_str,而不是to_s):

str = rb_funcall(str, rb_intern("to_s"), 0);

如果您希望这只适用于符号,则可以明确检查它们。在这种情况下,如果需要,可以直接调用为符号实现to_s的函数(如果你这样做,即使你打开Symbol#to_s类并更换它,也会始终使用原始的Symbol它有不同的实现):

if (TYPE(str) == T_SYMBOL) {
  str = rb_sym_to_s(str);
}

另一个选择是rb_convert_type使用to_s方法,这是(据我所知)几乎相当于只调用to_s

str = rb_convert_type(str, T_STRING, "String", "to_s");