Question

Writing a C extension for a Ruby gem, I need to test a parameter value for equality with a known symbol and string.

I realize you can intern a string with

char *foo = "foo";
VALUE foo_string_value = rb_intern(foo);

and then convert it into a symbol:

VALUE foo_sym_value = ID2SYM(foo_string_value);

My question is whether I can now reliably test the parameter, which may be a symbol or string, :foo or 'foo', with these using C pointer equality:

if (param == foo_string_value || param == foo_sym_value) {
  ...
}

In other words, does the interning guarantee that pointer equality is also value equality for symbols and strings?

If this is the wrong approach, then what's the right one to do this comparison?

Was it helpful?

Solution

I figured this out. A reasonable way to do what I want appears to be

VALUE square_sym = ID2SYM(rb_intern("square"));
VALUE kind_as_sym = rb_funcall(kind_value, rb_intern("to_sym"), 0);
if (square_sym == kind_as_sym) {
  ...
}

Symbols are always interned and have unique values. Strings aren't and don't. They can be interned to get IDs that are integers unique for each string, but that doesn't help in this case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top