Project

General

Profile

Feature #10214

new functions for compare of symbols in C API

Added by Hanmac (Hans Mackowiak) over 6 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:64841]

Description

currently i often use Symbols as enums in my bindings,
have something like this with comparing symbols by their ID

if(SYMBOL_P(sym))
{
  if(rb_intern("name") == SYM2ID(sym))
    return ENUM_NAME;
}

now with dynamic symbols and other ones, its problematic because with that i always foce a dynamic symbol to become static or pinned (that what SYM2ID does)

so imo there need to be better ways to compare is an ID and a VALUE-sym or two VALUE-syms and check if they have the same content (hm because comparing two VALUE with == might/does not work)

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

  • Status changed from Open to Feedback

You can do

ID2SYM(rb_intern("name")) == sym

rb_intern creates a permanent ID which never changes.

Updated by Hanmac (Hans Mackowiak) over 6 years ago

i need to check it, is the VALUE object the same pointer for symbols with same content? (because some might be static and the other dynamic, so == of the VALUE might not work)

i think thats only the case if the ID object is greated first before the dynamic symbol is maked in ruby

in a case where a symbol is created dynamicly and then a static symbol is created with the same content
i dont think the VALUE pointer of them would be the same (and i also need to check what happen to the dynamic symbol, because i dont think its getting static but it might become a pinned one)

Updated by ko1 (Koichi Sasada) over 6 years ago

(2014/09/08 18:06), hanmac@gmx.de wrote:

i need to check it, is the VALUE object the same pointer for symbols with same content? (because some might be static and the other dynamic, so == of the VALUE might not work)

did you verify it?
it might work.

--
// SASADA Koichi at atdot dot net

Updated by Hanmac (Hans Mackowiak) over 6 years ago

i did some testing with that if someone is interested:


#include <ruby.h>

VALUE is_dyn(VALUE self)
{
    return DYNAMIC_SYM_P(self) ? Qtrue : Qfalse;
}

VALUE check_symbol(VALUE self)
{
    VALUE str = rb_sym2str(self);
    ID id = rb_intern(StringValueCStr(str));
    return ID2SYM(id) == self ? Qtrue : Qfalse;
}

VALUE check_symbol_is_dyn(VALUE self)
{
    VALUE str = rb_sym2str(self);
    ID id = rb_intern(StringValueCStr(str));
    return DYNAMIC_SYM_P(ID2SYM(id)) ? Qtrue : Qfalse;
}

void Init_symtest()
{
    rb_define_method(rb_cSymbol,"dynamic?",is_dyn,0);
    rb_define_method(rb_cSymbol,"check",check_symbol,0);
    rb_define_method(rb_cSymbol,"check_dyn",check_symbol_is_dyn,0);
};

s="xyzed".to_sym #=> :xyzed
s.dynamic? #=> true
s.check #=> true
s.dynamic? #=> true
s.check_dyn #=> true

hm means that the check does works better than i thought ... hm the only thing i think that might happen is that ID2SYM(rb_intern(chr)) not allways returns a static symbol ... so it might be safer to still store the ID values and make symbols out of them when needed, because currently dont know what worse could happen ...

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

If an ID has been created by pinning down with ID2SYM, rb_intern returns that ID, and ditto for Symbols.

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

  • Description updated (diff)
  • Status changed from Feedback to Closed

Also available in: Atom PDF