Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Extending Ruby with C
Search
Paul Mucur
May 08, 2012
Programming
1
280
Extending Ruby with C
A Learning Lunch presentation about writing C extensions for Ruby.
Paul Mucur
May 08, 2012
Tweet
Share
More Decks by Paul Mucur
See All by Paul Mucur
Do you really need breakfast?
mudge
0
120
HyperLogLog in 15 minutes
mudge
0
180
Exploring #to_proc
mudge
0
160
Testing Vimscript with Vimrunner
mudge
3
200
Configuration Management with Puppet
mudge
1
220
Managing Web Application Servers with Puppet
mudge
3
140
Other Decks in Programming
See All in Programming
Snowflakeで眠ったデータを起こそう!
estie
0
140
Implementing Design Systems in Swift
seyfoyun
1
440
デフォルトにして至高、RubyMineの大好きな所
ruzia
0
700
障害対応を起点としたもっといい開発と運用のサイクル作りのためにできること / Hatena Enginner Seminar #29
polamjag
0
350
初心者のためのRubyKaigi入門/RubyKaigi Introduction
a_matsuda
8
1.4k
サイコロで理解する統計的仮説検定の考え方
tatamiya
4
1k
if constexpr文はテンプレート世界のラムダ式である
faithandbrave
3
670
try! Swift Tokyo 2024 参加報告 / try! Swift Tokyo 2024 Report
hironytic
0
220
StoreKit2によるiOSのアプリ内課金のリニューアル
kangnux
0
120
SIMD Parallel Programming with the Vector API
josepaumard
0
220
Ruby GitHub Packages
bkuhlmann
0
640
2 週間で Twitter Bot を作ってみた
contour_gara
0
760
Featured
See All Featured
RailsConf 2023
tenderlove
8
550
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
501
140k
Code Review Best Practice
trishagee
56
15k
Building Flexible Design Systems
yeseniaperezcruz
320
37k
Unsuck your backbone
ammeep
663
57k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
104
6.6k
Build The Right Thing And Hit Your Dates
maggiecrowley
25
2k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
242
1.2M
The World Runs on Bad Software
bkeepers
PRO
61
6.7k
Become a Pro
speakerdeck
PRO
12
4.6k
Web Components: a chance to create the future
zenorocha
306
41k
A Tale of Four Properties
chriscoyier
152
22k
Transcript
EXTENDING RUBY with C
Why?
PERFORMANCE
PERFORMANCE
C BINDINGS
C BINDINGS FFI
None
None
array << 1
static VALUE rb_ary_push_1(VALUE ary, VALUE item) {
long idx = RARRAY_LEN(ary); if (idx >= ARY_CAPA(ary)) { ary_double_capa(ary, idx); } RARRAY_PTR(ary)[idx] = item; ARY_SET_LEN(ary, idx + 1); return ary; }
EXT/WORLD/WORLD.C
> World.hello => "Hello, World!"
require "world" describe World do describe "#hello" do
it "greets the world" do World.hello.should == "Hello, World!" end end end
module World module_function def hello
"Hello, World!" end end
None
HELLO
return rb_str_new("Hello, World!", 13);
static VALUE world_hello(VALUE obj) { return rb_str_new("Hello, World!", 13);
}
WORLD
VALUE world_mWorld = rb_define_module("World"); rb_define_module_function(world_mWorld, "hello", world_hello,
0);
#include <ruby.h> static VALUE world_hello(VALUE obj) { return rb_str_new("Hello,
World!", 13); } void Init_world(void) { VALUE world_mWorld = rb_define_module("World"); rb_define_module_function(world_mWorld, "hello", world_hello, 0); }
COMPILATION
require "mkmf"
require "mkmf" $CFLAGS << " -‐Wall -‐Wextra" create_makefile("world")
$ ruby ext/world/extconf.rb creating Makefile
$ make compiling ext/world/world.c linking shared-‐object world.bundle
$ rspec spec/world_spec.rb . Finished in 0.00399 seconds 1
example, 0 failures
None
$ rake compile
require 'rake/extensiontask' require 'rspec/core/rake_task' Rake::ExtensionTask.new('world') RSpec::Core::RakeTask.new('test') task :test
=> :compile task :default => :test
it "greets someone by name, if given" do World.hello("Bob").should
== "Hello, Bob!" end
“If argc is -1, the function will be called as:
VALUE func(int argc, VALUE *argv, VALUE obj) where argc is the actual number of arguments, argv is the C array of the arguments, and obj is the receiver.”
def hello(name = nil) if name
"Hello, #{name}!" else "Hello, World!" end end
rb_define_module_function(world_mWorld, "hello", world_hello, -‐1);
static VALUE world_hello(int argc, VALUE *argv, VALUE obj) {
VALUE name; rb_scan_args(argc, argv, "01", &name); ... }
static VALUE world_hello(int argc, VALUE *argv, VALUE obj) {
VALUE name; rb_scan_args(argc, argv, "01", &name); if (NIL_P(name)) { return rb_str_new("Hello, World!", 13); } else { ... } }
static VALUE world_hello(int argc, VALUE *argv, VALUE obj) {
VALUE name, greeting; rb_scan_args(argc, argv, "01", &name); if (NIL_P(name)) { greeting = rb_str_new("Hello, World!", 13); } else { greeting = rb_str_new("Hello, ", 7); rb_str_cat(greeting, RSTRING_PTR(name), RSTRING_LEN(name)); rb_str_cat(greeting, "!", 1); } return greeting; }
$ rake clean test rm -‐r tmp/x86_64-‐darwin11.3.0/world/1.9.3 mkdir -‐p tmp/x86_64-‐darwin11.3.0/world/1.9.3
cd tmp/x86_64-‐darwin11.3.0/world/1.9.3 /Users/mudge/.rbenv/versions/1.9.3-‐p125/bin/ruby -‐ I. ../../../../ext/world/extconf.rb creating Makefile cd -‐ cd tmp/x86_64-‐darwin11.3.0/world/1.9.3 make compiling ../../../../ext/world/world.c linking shared-‐object world.bundle cd -‐ install -‐c tmp/x86_64-‐darwin11.3.0/world/1.9.3/world.bundle lib/ world.bundle /Users/mudge/.rbenv/versions/1.9.3-‐p125/bin/ruby -‐S rspec ./ spec/world_spec.rb .. Finished in 0.00081 seconds 2 examples, 0 failures
None
QUESTIONS?