tomato 0.0.1.prealpha1 → 0.0.1.prealpha2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,44 +20,105 @@ hope to release it as a real gem after it's reached a sufficient level of functi
20
20
  When JS code is executed, it'll do its thing internally and then return the result:
21
21
 
22
22
  tomato.run("(1+1);") # => 2
23
+
24
+ ==== Bindings
25
+
26
+ You can bind Ruby methods to JavaScript, as well. You can bind an instance method of Tomato like so:
27
+
28
+ tomato.bind_method(:inspect)
29
+ tomato.run("inspect();") #=> "#<Tomato>"
23
30
 
24
- When JS code encounters an error of some kind, it'll get raised in Ruby:
31
+ Or, perhaps more usefully, you can bind an instance method of some other object:
25
32
 
26
- tomato.run("throw 'error';")
33
+ tomato.bind_method(:inspect, 5)
34
+ tomato.run("inspect();") #=> "5"
27
35
 
36
+ It's also easy to bind methods to arbitrary JavaScript objects. If a JS object in the chain doesn't exist, Tomato will
37
+ silently generate it for you on-the-fly:
38
+
39
+
40
+ def say(something)
41
+ puts something
42
+ end
43
+
44
+ tomato.bind_method(:say, self, :to => "person.mouth")
45
+
46
+ # Tomato generated both the "person" and "mouth" objects for us:
47
+ tomato.run "person.mouth.say('Hello there');"
48
+
28
49
  # Produces:
29
- #
30
- # Tomato::Error: (dynamic):error
31
- # throw 'error';
32
- # ^
33
50
  #
34
- # from (irb):3:in `run'
35
- # from (irb):3
51
+ # Hello there
52
+ # => nil
53
+
54
+ puts tomato.run("this")
36
55
 
37
- You can bind Ruby methods to JavaScript, as well. CURRENTLY only Tomato instance methods are supported. This will be
38
- extended in the near future to include any method on any object. Current implementation of method binding looks like
39
- this:
56
+ # Produces:
57
+ #
58
+ # {"person":{"mouth":{}}}
59
+ # => nil
40
60
 
41
- tomato.bind_method(:inspect)
42
- tomato.run("inspect();") #=> "#<Tomato>"
61
+ In the spirit of true Ruby dynamicism, (is that a word?), you can feel free to re-bind new methods over old ones:
62
+
63
+ tomato.bind_method(:say)
64
+ tomato.run("say('something');")
65
+ #=> error! say is not an instance method of Tomato
43
66
 
44
- For now (until a better method binding is implemented) you can add methods. You can do this before OR after binding it:
67
+ tomato.bind_method(:say, self)
68
+ def say(something); puts something; end
69
+ tomato.run("say('something');")
70
+ #=> something
71
+
72
+ You can also easily bind an entire object to JavaScript:
45
73
 
46
- tomato.bind_method(:say_hello)
47
- def tomato.say_hello
48
- puts "Hi there!"
74
+ # By default objects are mapped to 'ruby.[object_class_name]'
75
+ tomato.bind_object(Time.now)
76
+ tomato.run("ruby.time.to_s();")
77
+ #=> "2010-06-25 18:12:23 -0400"
78
+
79
+ # Or give it an object name or chain of names:
80
+ tomato.bind_object(Time.now, "time.current")
81
+ tomato.run("time.current.to_s();")
82
+ #=> "2010-06-25 18:12:23 -0400"
83
+
84
+ Even better, you can also bind a whole class and instantiate it from within JavaScript. If you return the object to
85
+ Ruby, it'll be seamlessly converted into the corresponding Ruby object.
86
+
87
+ class Person
88
+ def initialize(name)
89
+ @name = name
90
+ end
91
+ attr_accessor :name, :age
49
92
  end
50
- tomato.run("say_hello();")
93
+
94
+ tomato.bind_object(Person, "world.Person")
95
+ tomato.run <<-end_js
96
+ var colin = new world.Person("Colin");
97
+ colin.age = 25;
98
+ colin;
99
+ end_js
100
+
101
+ #=> #<Person:0x00000100dbbc50 @name="Colin", @age=25>
102
+
103
+ ==== Error Handling
104
+
105
+ When JS code encounters an error of some kind, it'll get raised in Ruby:
106
+
107
+ tomato.run("throw 'error';")
51
108
 
52
109
  # Produces:
110
+ #
111
+ # Tomato::Error: (dynamic):error
112
+ # throw 'error';
113
+ # ^
53
114
  #
54
- # Hi there!
55
- # => nil
115
+ # from (irb):3:in `run'
116
+ # from (irb):3
56
117
 
57
118
  You can also catch Ruby errors in JavaScript:
58
119
 
59
- tomato.bind_method(:raise_err)
60
- def tomato.raise_err
120
+ tomato.bind_method(:raise_err, self)
121
+ def raise_err
61
122
  raise ArgumentError, "Not what I meant!"
62
123
  end
63
124
  tomato.run("try { raise_err(); } catch(e) {}");
@@ -68,8 +129,8 @@ You can also catch Ruby errors in JavaScript:
68
129
 
69
130
  Or let them bubble up to Ruby:
70
131
 
71
- tomato.bind_method(:raise_err)
72
- def tomato.raise_err
132
+ tomato.bind_method(:raise_err, self)
133
+ def raise_err
73
134
  raise ArgumentError, "Not what I meant!"
74
135
  end
75
136
  begin
@@ -83,8 +144,6 @@ Or let them bubble up to Ruby:
83
144
  # Error: Not what I meant!
84
145
  # => nil
85
146
 
86
- That's all I've implemented so far, but I think it looks pretty cool.
87
-
88
147
  === Object Types
89
148
 
90
149
  Some objects in Ruby don't exist in JS. So far the ones I've implemented are Hashes and Symbols.
@@ -92,7 +151,17 @@ Some objects in Ruby don't exist in JS. So far the ones I've implemented are Has
92
151
  ==== Symbols
93
152
 
94
153
  A Symbol is converted to an object in JS with a "symbol" attribute and a "toString()" method. That same object, if
95
- returned to Ruby, is converted back to a Symbol.
154
+ returned to Ruby, is converted back to a Symbol. Examples:
155
+
156
+ def fetch_a_symbol
157
+ :a_symbol
158
+ end
159
+
160
+ t = Tomato.new
161
+ t.bind_method(:fetch_a_symbol, self)
162
+ t.run("fetch_a_symbol()") #=> :a_symbol
163
+ t.run("fetch_a_symbol().symbol") #=> "a_symbol"
164
+ t.run("fetch_a_symbol().toString()") #=> "a_symbol"
96
165
 
97
166
 
98
167
  ==== Hashes
@@ -127,11 +196,26 @@ That should be all there is to it.
127
196
 
128
197
  == Performance
129
198
 
130
- Too early to tell. Benchmarking will be done as I get closer to a real release.
199
+ ruby-1.9.1-p378 > javascript = <<-end_js
200
+ ruby-1.9.1-p378"> var str = "";
201
+ ruby-1.9.1-p378"> for (var i = 0; i < 1000000; i++)
202
+ ruby-1.9.1-p378"> str = 'a';
203
+ ruby-1.9.1-p378"> end_js
204
+ ruby-1.9.1-p378 > require 'benchmark'
205
+ ruby-1.9.1-p378 > require 'tomato'
206
+ ruby-1.9.1-p378 > t = Tomato.new
207
+ ruby-1.9.1-p378 >
208
+ ruby-1.9.1-p378 > # Setup complete, let's start the test
209
+ ruby-1.9.1-p378 > puts Benchmark.measure { for i in 1..1000000; str = 'a'; end }
210
+ ruby-1.9.1-p378 > 0.350000 0.000000 0.350000 ( 0.358106)
211
+ ruby-1.9.1-p378 >
212
+ ruby-1.9.1-p378 > puts Benchmark.measure { t.run(javascript) }
213
+ ruby-1.9.1-p378 > 0.010000 0.000000 0.010000 ( 0.012603)
214
+
215
+ 'Nuff said.
131
216
 
132
- Since V8's JavaScript code is compiled into byte code, this MAY (untested) have a positive impact on performance
133
- in some applications. Just translate your code to JavaScript and let V8 compile it to byte code. I'm hoping for some
134
- cool results.
217
+ Since V8's JavaScript code is compiled into byte code, this can have a positive impact on performance
218
+ in some applications. Just translate your code to JavaScript and let Tomato compile it into byte code.
135
219
 
136
220
  == Note on Patches/Pull Requests
137
221
 
data/Rakefile CHANGED
@@ -11,6 +11,7 @@ begin
11
11
  gem.email = "sinisterchipmunk@gmail.com"
12
12
  gem.homepage = "http://www.thoughtsincomputation.com"
13
13
  gem.authors = ["Colin MacKenzie IV"]
14
+ gem.add_dependency "sc-core-ext", ">= 1.2.0"
14
15
  gem.add_development_dependency "rspec", ">= 1.3.0"
15
16
  gem.files = FileList['**/*']
16
17
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1.prealpha1
1
+ 0.0.1.prealpha2
@@ -4,19 +4,17 @@ SHELL = /bin/sh
4
4
  #### Start of system configuration section. ####
5
5
 
6
6
  srcdir = .
7
- topdir = /Users/colin/.rvm/rubies/ruby-1.9.2-preview3/include/ruby-1.9.1
8
- hdrdir = /Users/colin/.rvm/rubies/ruby-1.9.2-preview3/include/ruby-1.9.1
9
- arch_hdrdir = /Users/colin/.rvm/rubies/ruby-1.9.2-preview3/include/ruby-1.9.1/$(arch)
7
+ topdir = /Users/colin/.rvm/rubies/ruby-1.9.1-p378/include/ruby-1.9.1
8
+ hdrdir = /Users/colin/.rvm/rubies/ruby-1.9.1-p378/include/ruby-1.9.1
9
+ arch_hdrdir = /Users/colin/.rvm/rubies/ruby-1.9.1-p378/include/ruby-1.9.1/$(arch)
10
10
  VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
11
- prefix = $(DESTDIR)/Users/colin/.rvm/rubies/ruby-1.9.2-preview3
12
- rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
11
+ prefix = $(DESTDIR)/Users/colin/.rvm/rubies/ruby-1.9.1-p378
13
12
  exec_prefix = $(prefix)
14
13
  vendorhdrdir = $(rubyhdrdir)/vendor_ruby
15
14
  sitehdrdir = $(rubyhdrdir)/site_ruby
16
- rubyhdrdir = $(includedir)/$(RUBY_BASE_NAME)-$(ruby_version)
17
- vendordir = $(rubylibprefix)/vendor_ruby
18
- sitedir = $(rubylibprefix)/site_ruby
19
- ridir = $(datarootdir)/$(RI_BASE_NAME)
15
+ rubyhdrdir = $(includedir)/$(RUBY_INSTALL_NAME)-$(ruby_version)
16
+ vendordir = $(libdir)/$(RUBY_INSTALL_NAME)/vendor_ruby
17
+ sitedir = $(libdir)/$(RUBY_INSTALL_NAME)/site_ruby
20
18
  mandir = $(datarootdir)/man
21
19
  localedir = $(datarootdir)/locale
22
20
  libdir = $(exec_prefix)/lib
@@ -36,7 +34,7 @@ datarootdir = $(prefix)/share
36
34
  libexecdir = $(exec_prefix)/libexec
37
35
  sbindir = $(exec_prefix)/sbin
38
36
  bindir = $(exec_prefix)/bin
39
- rubylibdir = $(rubylibprefix)/$(ruby_version)
37
+ rubylibdir = $(libdir)/$(ruby_install_name)/$(ruby_version)
40
38
  archdir = $(rubylibdir)/$(arch)
41
39
  sitelibdir = $(sitedir)/$(ruby_version)
42
40
  sitearchdir = $(sitelibdir)/$(sitearch)
@@ -53,35 +51,34 @@ OUTFLAG = -o
53
51
  COUTFLAG = -o
54
52
 
55
53
  RUBY_EXTCONF_H =
56
- cflags = $(optflags) $(debugflags) $(warnflags)
57
- optflags = -O3
58
- debugflags = -ggdb
59
- warnflags = -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wshorten-64-to-32 -Wno-long-long
60
- CFLAGS = -fno-common $(cflags) -fno-common -pipe
54
+ cflags = $(optflags) $(debugflags) $(warnflags)
55
+ optflags = -O2
56
+ debugflags = -g
57
+ warnflags = -Wall -Wno-parentheses
58
+ CFLAGS = -fno-common $(cflags) -fno-common -pipe -fno-common
61
59
  INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) -I/Users/colin/projects/gems/tomato/ext/tomato/external/build/v8/include
62
60
  DEFS =
63
- CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags) -Wall -g -rdynamic
64
- CXXFLAGS = $(CFLAGS) $(cxxflags)
61
+ CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags) -Wall -g -rdynamic
62
+ CXXFLAGS = $(CFLAGS) $(cxxflags)
65
63
  ldflags = -L. -L/usr/local/lib
66
- dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -Wl,-flat_namespace
67
- ARCH_FLAG =
68
- DLDFLAGS = $(ldflags) $(dldflags)
69
- LDSHARED = $(CC) -dynamic -bundle
70
- LDSHAREDXX = $(CXX) -dynamic -bundle
64
+ dldflags =
65
+ archflag =
66
+ DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
67
+ LDSHARED = cc -dynamic -bundle -undefined suppress -flat_namespace
68
+ LDSHAREDXX = $(LDSHARED)
71
69
  AR = ar
72
70
  EXEEXT =
73
71
 
74
- RUBY_BASE_NAME = ruby
75
72
  RUBY_INSTALL_NAME = ruby
76
- RUBY_SO_NAME = ruby.1.9.1
77
- arch = x86_64-darwin10.4.0
78
- sitearch = $(arch)
73
+ RUBY_SO_NAME = ruby
74
+ arch = i386-darwin10.4.0
75
+ sitearch = i386-darwin10.4.0
79
76
  ruby_version = 1.9.1
80
- ruby = /Users/colin/.rvm/rubies/ruby-1.9.2-preview3/bin/ruby
77
+ ruby = /Users/colin/.rvm/rubies/ruby-1.9.1-p378/bin/ruby
81
78
  RUBY = $(ruby)
82
79
  RM = rm -f
83
80
  RM_RF = $(RUBY) -run -e rm -- -rf
84
- RMDIRS = rmdir -p
81
+ RMDIRS = $(RUBY) -run -e rmdir -- -p
85
82
  MAKEDIRS = mkdir -p
86
83
  INSTALL = /usr/bin/install -c
87
84
  INSTALL_PROG = $(INSTALL) -m 0755
@@ -104,9 +101,9 @@ extout =
104
101
  extout_prefix =
105
102
  target_prefix =
106
103
  LOCAL_LIBS =
107
- LIBS = $(LIBRUBYARG_SHARED) -lobjc -lpthread -lpthread -ldl -lobjc -lv8
108
- SRCS = binding_methods.cpp conversions_to_js.cpp conversions_to_rb.cpp errors.cpp tomato.cpp v8.cpp
109
- OBJS = binding_methods.o conversions_to_js.o conversions_to_rb.o errors.o tomato.o v8.o
104
+ LIBS = $(LIBRUBYARG_SHARED) -lobjc -lpthread -lpthread -ldl -lobjc -lv8
105
+ SRCS = binding_methods.cpp conversions_to_js.cpp conversions_to_rb.cpp errors.cpp object_chain.cpp tomato.cpp v8.cpp
106
+ OBJS = binding_methods.o conversions_to_js.o conversions_to_rb.o errors.o object_chain.o tomato.o v8.o
110
107
  TARGET = tomato
111
108
  DLLIB = $(TARGET).bundle
112
109
  EXTSTATIC =
@@ -125,8 +122,6 @@ CLEANOBJS = *.o *.bak
125
122
 
126
123
  all: $(DLLIB)
127
124
  static: $(STATIC_LIB)
128
- .PHONY: all install static install-so install-rb
129
- .PHONY: clean clean-so clean-rb
130
125
 
131
126
  clean-rb-default::
132
127
  clean-rb::
@@ -148,8 +143,7 @@ install: install-so install-rb
148
143
  install-so: $(RUBYARCHDIR)
149
144
  install-so: $(RUBYARCHDIR)/$(DLLIB)
150
145
  $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
151
- @-$(MAKEDIRS) $(@D)
152
- $(INSTALL_PROG) $(DLLIB) $(@D)
146
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
153
147
  install-rb: pre-install-rb install-rb-default
154
148
  install-rb-default: pre-install-rb-default
155
149
  pre-install-rb: Makefile
@@ -185,14 +179,15 @@ $(DLLIB): $(OBJS) Makefile
185
179
 
186
180
 
187
181
  ###
188
- binding_methods.o: binding_methods.cpp tomato.h
182
+ binding_methods.o: binding_methods.cpp tomato.h binding_methods.h
189
183
  conversions_to_js.o: conversions_to_js.cpp tomato.h
190
184
  conversions_to_rb.o: conversions_to_rb.cpp tomato.h
191
185
  errors.o: errors.cpp tomato.h
186
+ object_chain.o: object_chain.cpp tomato.h binding_methods.h
192
187
  tomato.o: tomato.cpp tomato.h
193
188
  v8.o: v8.cpp tomato.h
194
189
 
195
190
  test: all
196
191
  @echo Running specs...
197
- spec -O spec/spec.opts spec
192
+ spec spec -c
198
193
 
@@ -1,9 +1,7 @@
1
1
  #include "tomato.h"
2
+ #include "binding_methods.h"
2
3
 
3
4
  static VALUE bound_method_call(VALUE args);
4
- static Handle<Value> bound_method(const Arguments& args);
5
- static int store_rb_message(const Arguments &args, V8Tomato **out_tomato, VALUE *out_receiver, ID *out_method_id);
6
-
7
5
 
8
6
  Handle<Value> bound_method(const Arguments& args)
9
7
  {
@@ -13,12 +11,17 @@ Handle<Value> bound_method(const Arguments& args)
13
11
  ID rb_method_id;
14
12
  V8Tomato *tomato;
15
13
  int code = store_rb_message(args, &tomato, &receiver, &rb_method_id);
16
- if (code == -1)
17
- return ThrowException(String::New("Error: _tomato is not an object (BUG: please report)"));
14
+ switch(code)
15
+ {
16
+ case -1: return ThrowException(String::New("Error: _tomato is not an object (BUG: please report)"));
17
+ case -2: return ThrowException(String::New("Error: _tomato_receiver_index is not an Int32 (BUG: please report)"));
18
+ case -3: return ThrowException(String::New("Error: _tomato_receiver_index is greater than @receivers.length (BUG: please report)"));
19
+ };
18
20
 
19
- VALUE rbargs = rb_ary_new2(2);
21
+ VALUE rbargs = rb_ary_new2(2+args.Length());
20
22
  rb_ary_store(rbargs, 0, receiver);
21
23
  rb_ary_store(rbargs, 1, ID2SYM(rb_method_id));
24
+ store_args(tomato, rbargs, args);
22
25
 
23
26
  int error;
24
27
  VALUE result = rb_protect(bound_method_call, rbargs, &error);
@@ -30,27 +33,50 @@ Handle<Value> bound_method(const Arguments& args)
30
33
  return js_value_of(tomato, result);
31
34
  }
32
35
 
36
+ void store_args(V8Tomato *tomato, VALUE rbargs, const Arguments &args)
37
+ {
38
+ int length = args.Length();
39
+ int offset = RARRAY_LEN(rbargs);
40
+ for (int i = 0; i < length; i++)
41
+ rb_ary_store(rbargs, offset+i, ruby_value_of(tomato, args[i]));
42
+ }
43
+
33
44
  static VALUE bound_method_call(VALUE args)
34
45
  {
35
- VALUE receiver = rb_ary_entry(args, 0);
36
- VALUE rb_method_id = SYM2ID(rb_ary_entry(args, 1));
37
-
38
- VALUE result = rb_funcall(receiver, rb_method_id, 0);
39
-
46
+ VALUE receiver = rb_ary_shift(args);
47
+ VALUE rb_method_id = SYM2ID(rb_ary_shift(args));
48
+ VALUE result = rb_funcall2(receiver, rb_method_id, RARRAY_LEN(args), RARRAY_PTR(args));
40
49
  return result;
41
50
  }
42
51
 
43
52
  int store_rb_message(const Arguments &args, V8Tomato **out_tomato, VALUE *out_receiver, ID *out_method_id)
44
53
  {
54
+ // get the function
45
55
  Handle<Function> function = args.Callee();
46
- Handle<String> _tomato = String::New("_tomato");
47
- if (!function->Get(_tomato)->IsExternal())
48
- return -1;
56
+
57
+ // pull the binding data from the function (stored there by fTomato_bind_method)
58
+ Local<Value> v8_tomato = function->Get(String::New("_tomato"));
59
+ Local<Value> v8_receiver_index = function->Get(String::New("_tomato_receiver_index"));
60
+
61
+ // make sure the data is what we expect it to be
62
+ if (!v8_tomato->IsExternal()) return -1;
63
+ if (!v8_receiver_index->IsInt32()) return -2;
49
64
 
50
- V8Tomato *tomato = (V8Tomato *)Local<External>::Cast(function->Get(_tomato))->Value();
51
- VALUE receiver = tomato->rb_instance;
65
+ // find the tomato
66
+ V8Tomato *tomato = (V8Tomato *)Local<External>::Cast(v8_tomato)->Value();
67
+
68
+ // find the receiver index, and make sure it's a valid index
69
+ int receiver_index = v8_receiver_index->Int32Value();
70
+ VALUE receivers = rb_iv_get(tomato->rb_instance, "@receivers"); //rb_funcall(tomato->rb_instance, rb_intern("receivers"));
71
+ if (RARRAY_LEN(receivers) < receiver_index) return -3;
72
+
73
+ // get the receiver
74
+ VALUE receiver = (RARRAY_PTR(receivers)[receiver_index]);
75
+
76
+ // get the method name from the function name
52
77
  String::Utf8Value method_name(function->GetName());
53
78
 
79
+ // store the output and return success.
54
80
  *out_tomato = tomato;
55
81
  *out_method_id = rb_intern(ToCString(method_name));
56
82
  *out_receiver = receiver;
@@ -59,22 +85,23 @@ int store_rb_message(const Arguments &args, V8Tomato **out_tomato, VALUE *out_re
59
85
 
60
86
  VALUE fTomato_bind_method(int argc, VALUE *argv, VALUE self)
61
87
  {
62
- if (argc != 1) rb_raise(rb_eArgError, "Expected name of method");
88
+ if (argc != 3) rb_raise(rb_eArgError,
89
+ "Expected: _bind_method(method_name<str>, receiver_index<int>, object_chain<array[string] or nil>)");
63
90
  const char *method_name = rb_id2name(rb_to_id(argv[0]));
64
91
 
65
92
  V8Tomato *tomato;
66
93
  Data_Get_Struct(self, V8Tomato, tomato);
67
94
 
68
95
  HandleScope handle_scope;
69
- Context::Scope context_scope(tomato->context);
70
- Handle<Value> value = tomato->context->Global();
96
+ Context::Scope context_scope(tomato->context);
97
+ Handle<Value> value = find_or_create_object_chain(tomato, argv[2]);
71
98
  if (value->IsObject())
72
99
  {
73
100
  Handle<Object> object = Handle<Object>::Cast(value);
74
- Handle<Value> proto_value = object->GetPrototype();
75
101
  Handle<Function> function = FunctionTemplate::New(bound_method)->GetFunction();
76
102
 
77
103
  function->Set(String::New("_tomato"), External::New(tomato));
104
+ function->Set(String::New("_tomato_receiver_index"), Int32::New(FIX2INT(argv[1])));
78
105
  function->SetName(String::New(method_name));
79
106
 
80
107
  object->Set(String::New(method_name), function);