Question about NUM2LONG, symbols

D

Daniel Berger

Hi all,

The various NUM2x functions (NUM2LONG, NUM2INT, etc) include builtin type
checks. However, they still seem to blindly accept symbols. Why?

/* foo.c */
#include "ruby.h"
#include <stdio.h>

static VALUE foo_test(VALUE self, VALUE num)
{
long x;
x = NUM2LONG(num);

printf("NUM: %ld\n", x);

return Qnil;
}

void Init_foo(){
VALUE cFoo = rb_define_class("Foo", rb_cObject);
rb_define_method(cFoo, "test", foo_test, 1);
}

# foo.rb
require "foo"

Foo.new.test("foo") # TypeError, expected
Foo.new.test("foo".to_sym) # NUM: 10201 - yikes!

Regards,

Dan
 
T

ts

D> Foo.new.test("foo".to_sym) # NUM: 10201 - yikes!

moulon% cat aa.c
#include "ruby.h"
#include <stdio.h>

static VALUE
aa_to_int(VALUE self)
{
return INT2FIX(12);
}

static VALUE
aa_test(VALUE self)
{
printf("NUM: %ld\n", NUM2LONG(self));

return Qnil;
}

void Init_aa(){
VALUE cAa = rb_define_class("Aa", rb_cObject);
rb_define_method(cAa, "test", aa_test, 0);
rb_define_method(cAa, "to_int", aa_to_int, 0);
}

moulon%

moulon% ruby -raa -e 'Aa.new.test'
NUM: 12
moulon%


Guy Decoux
 
D

Daniel Berger

ts said:
D> Foo.new.test("foo".to_sym) # NUM: 10201 - yikes!

moulon% cat aa.c
#include "ruby.h"
#include <stdio.h>

static VALUE
aa_to_int(VALUE self)
{
return INT2FIX(12);
}

static VALUE
aa_test(VALUE self)
{
printf("NUM: %ld\n", NUM2LONG(self));

return Qnil;
}

void Init_aa(){
VALUE cAa = rb_define_class("Aa", rb_cObject);
rb_define_method(cAa, "test", aa_test, 0);
rb_define_method(cAa, "to_int", aa_to_int, 0);
}

moulon%

moulon% ruby -raa -e 'Aa.new.test'
NUM: 12
moulon%


Guy Decoux

Ok, thanks Guy, I get it - internally it calls rb_num2long(), which in turn
tries to call a to_int method. Since the Symbol class defines to_int, I get
that result.

I guess it would be nice if we had a macro that raised a TypeError on anything
except a Fixnum, Float or Bignum. Otherwise, aren't all C extension writers
relegated to doing explicit checks against Symbols (the way rb_ary_ref() does
in array.c) if we really want to make our code bulletproof? That, or lots of
Check_Type() functions sprinkled throughout our code?

I suppose I just want a version of rb_num2long() that changes the default in
the switch statement to something like this:

default:
rb_raise(rb_eTypeError, "not a Fixnum, Float or Bignum");

Thanks,

Dan
 
N

nobu.nokada

Hi,

At Fri, 4 Nov 2005 02:02:35 +0900,
Daniel Berger wrote in [ruby-talk:163946]:
I guess it would be nice if we had a macro that raised a TypeError on anything
except a Fixnum, Float or Bignum. Otherwise, aren't all C extension writers
relegated to doing explicit checks against Symbols (the way rb_ary_ref() does
in array.c) if we really want to make our code bulletproof? That, or lots of
Check_Type() functions sprinkled throughout our code?

An object has :to_int method should be treated as an Integer.
It's duck-typing, isn't it? Symbol no longer has that method
in 1.9.
 
D

Daniel Berger

Hi,

At Fri, 4 Nov 2005 02:02:35 +0900,
Daniel Berger wrote in [ruby-talk:163946]:
I guess it would be nice if we had a macro that raised a TypeError on anything
except a Fixnum, Float or Bignum. Otherwise, aren't all C extension writers
relegated to doing explicit checks against Symbols (the way rb_ary_ref() does
in array.c) if we really want to make our code bulletproof? That, or lots of
Check_Type() functions sprinkled throughout our code?

An object has :to_int method should be treated as an Integer.
It's duck-typing, isn't it? Symbol no longer has that method
in 1.9.

I understand the duck typing approach. However, I'm curious why
rb_ary_aref() explicitly forbids symbols as arguments. Can you tell me
why? Was there some unexpected side effect?

Thanks,

Dan
 
N

nobu.nokada

Hi,

At Sat, 5 Nov 2005 09:57:09 +0900,
Daniel Berger wrote in [ruby-talk:164299]:
I understand the duck typing approach. However, I'm curious why
rb_ary_aref() explicitly forbids symbols as arguments. Can you tell me
why? Was there some unexpected side effect?

In older versions, symbols were just integers, so Symbol has
to_int method. But it was considered inappropriate for array
index which is successive. It is like the appendix, and no
longer in 1.9.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top