MacRuby is an implementation of Ruby 1.9 that is directly on top of Mac OS X core technologies. Recently, MacRuby has become viable as a tool for developing useful desktop applications for Mac OS X. However, as of March 2011, MacRuby is still missing some functionality that is present in cRuby. Therefore, MacRuby is not able to run Ruby on Rails. In my presentation, I will explain how I modified MacRuby to make it a suitable foundation for running Rails. I would also like to explain some of technical intricacies that I discovered along the way.
(Japanese)
2011年3月時点でのMacRubyはRuby処理系としての完成度は低く、Ruby on Railsが到底動作するようには思えない。しかしながら、MacRubyに対して改良 に改良を重ねることできっとRailsを動作させることができる(はずである)。 本発表ではMacRubyでRailsを動作させるために必要だった修正内容とともに、 その過程であらためて知ることになったcRubyのすばらしさを説明します。
1. MacRuby on Rails
2011 3 MacRuby Ruby Ruby on Rails
MacRuby
Rails MacRuby Rails
cRuby
Abstract
MacRuby is an implementation of Ruby 1.9 that is directly on top of Mac OS X core technologies.
Recently, MacRuby has become viable as a tool for developing useful desktop applications for
Mac OS X. However, as of March 2011, MacRuby is still missing some functionality that is
present in cRuby. Therefore, MacRuby is not able to run Ruby on Rails. In my presentation, I will
explain how I modified MacRuby to make it a suitable foundation for running Rails. I would also
like to explain some of technical intricacies that I discovered along the way.
2011 7 19 1
13. MacRuby
MacRuby is a unique blend of Ruby 1.9 and
Objective-C.
➡ Ruby 1.9 Objective-C
2011 7 19 6
14. MacRuby
MacRuby is a unique blend of Ruby 1.9 and
Objective-C.
➡ Ruby 1.9 Objective-C
The goal of the MacRuby project is to be
100% compatible syntactically and
behaviorally with Ruby 1.9.
➡ Ruby 1.9
2011 7 19 6
15. Ruby 1.9
Ruby 1.9
Ruby VM
GC
OS
(Linux,Windows,Mac OS X,etc...)
2011 7 19 7
16. MacRuby
MacRuby
Ruby VM
GC
Mac OS X
2011 7 19 8
17. MacRuby
MacRuby
Ruby VM
GC
Mac OS X
2011 7 19 8
18. MacRuby
MacRuby
Ruby VM
AutoZone
GC
Mac OS X
2011 7 19 8
19. MacRuby
MacRuby
Ruby VM
AutoZone
GC
Foundation
Mac OS X
2011 7 19 8
20. MacRuby
MacRuby
AutoZone
LLVM
GC
Foundation
Mac OS X
2011 7 19 9
47. #860 catch/throw
Assertion fails in pop_current_exception
when catch/throw used in rescue
➡ rescue catch throw abort
2011 7 19 19
48. #860 catch/throw
Assertion fails in pop_current_exception
when catch/throw used in rescue
➡ rescue catch throw abort
begin
raise
rescue
catch(:ambiguous) { throw :ambiguous }
p :ok
end
2011 7 19 19
49. #860 catch/throw
Assertion fails in pop_current_exception
when catch/throw used in rescue
➡ rescue catch throw abort
begin
raise
rescue
catch(:ambiguous) { throw :ambiguous }
p :ok
end
:ok
Assertion failed: ((size_t)pos < current_exceptions.size()),
function pop_current_exception, file vm.cpp, line 3448.
2011 7 19 19
50. #860 catch/throw
Assertion fails in pop_current_exception
when catch/throw used in rescue
➡ rescue catch throw abort
throw
begin
raise
rescue
catch(:ambiguous) { throw :ambiguous }
p :ok
end
:ok
Assertion failed: ((size_t)pos < current_exceptions.size()),
function pop_current_exception, file vm.cpp, line 3448.
2011 7 19 19
51. #860 catch/throw
Assertion fails in pop_current_exception
when catch/throw used in rescue
➡ rescue catch throw abort
throw
begin
raise
rescue
catch(:ambiguous) { throw :ambiguous }
p :ok
end
:ok abort
Assertion failed: ((size_t)pos < current_exceptions.size()),
function pop_current_exception, file vm.cpp, line 3448.
2011 7 19 19
53. #860 catch/throw
(60723bf~) throw
catch(:ambiguous) {
begin
raise
rescue
throw :ambiguou
end
}
2011 7 19 20
54. #860 catch/throw
(60723bf~) throw
catch(:ambiguous) {
begin
raise
rescue
throw :ambiguou
end
} end
2011 7 19 20
55. #860 catch/throw
(60723bf~) throw
catch(:ambiguous) {
begin throw
raise
rescue
throw :ambiguou
end
} end
2011 7 19 20
56. #860 catch/throw
(60723bf~) throw
vm.cpp:4321:
catch(:ambiguous) {
VALUE begin throw
RoxorVM::ruby_throw(VALUE tag,VALUE value)
raise
{ rescue
... throw :ambiguou
// end must pop the current VM exception in case we are in a rescue handler,
We
// since we are going to unwind the stack.
} end
if (current_exception() != Qnil) {
pop_current_exception();
}
...
2011 7 19 20
60. #860 catch/throw
begin
raise
rescue
catch(:ambiguous) {
begin
raise
rescue
begin
raise
rescue
throw :ambiguous
end
end
}
p :ok
end
2011 7 19 22
61. #860 catch/throw
begin A
raise
rescue
catch(:ambiguous) {
begin
raise
rescue
begin
raise
rescue
throw :ambiguous
end
end
}
p :ok
end
2011 7 19 22
62. #860 catch/throw
begin A
raise A
rescue catch_ptr->current_exception = current_exception();
catch(:ambiguous) {
begin
raise
rescue
begin
raise
rescue
throw :ambiguous
end
end
}
p :ok
end
2011 7 19 22
63. #860 catch/throw
begin A
raise A
rescue catch_ptr->current_exception = current_exception();
catch(:ambiguous) {
begin B
raise
rescue
begin
raise
rescue
throw :ambiguous
end
end
}
p :ok
end
2011 7 19 22
64. #860 catch/throw
begin A
raise A
rescue catch_ptr->current_exception = current_exception();
catch(:ambiguous) {
begin B
raise
rescue
begin C
raise
rescue
throw :ambiguous
end
end
}
p :ok
end
2011 7 19 22
65. #860 catch/throw
begin A
raise A
rescue catch_ptr->current_exception = current_exception();
catch(:ambiguous) {
begin B
raise
rescue
begin C
raise
rescue C B A A
throw :ambiguous
C B
end
end
}
p :ok
end
2011 7 19 22
66. #860 catch/throw
begin A
raise A
rescue catch_ptr->current_exception = current_exception();
catch(:ambiguous) {
begin B
raise
rescue
begin C
raise
rescue C B A A
throw :ambiguous
C B
end
end
}
p :ok A
end
2011 7 19 22
67. #1192
Did not find nested constants.
➡
2011 7 19 23
68. #1192
Did not find nested constants.
➡
module A
B = 10
Object.class_eval { B }
end
2011 7 19 23
69. #1192
Did not find nested constants.
➡
module A
B = 10
Object.class_eval { B }
end
reduction.rb:3:in `block': uninitialized constant B (NameError)
from reduction.rb:1:in `<main>'
2011 7 19 23
70. #1192
Did not find nested constants.
➡
module A
Object B
B = 10
Object.class_eval { B }
end
reduction.rb:3:in `block': uninitialized constant B (NameError)
from reduction.rb:1:in `<main>'
2011 7 19 23
72. #1192
6b101bd~
module A
module B
CONST = “B’s Const”
module ::A
p CONST
end
end
end
2011 7 19 24
73. #1192
6b101bd~
module A
module B
CONST = “B’s Const”
module ::A
p CONST
end
end
end
-e:5:in `block': uninitialized constant A::CONST (NameError)
2011 7 19 24
74. #1192
6b101bd~
module A
module B
CONST = “B’s Const”
module ::A
p CONST ::A A::B A
end ::A
end
end
-e:5:in `block': uninitialized constant A::CONST (NameError)
2011 7 19 24
75. module_eval( ) module_eval
module A module A
CONST = "A's CONST" CONST = "A's CONST"
def f def f
class_eval <<-EOS class_eval {
p CONST p CONST
EOS }
end end
end end
class K class K
CONST = "K's CONST" CONST = "K's CONST"
extend A extend A
f f
end end
2011 7 19 25
76. module_eval( ) module_eval
module A module A
CONST = "A's CONST" CONST = "A's CONST"
def f def f
class_eval <<-EOS class_eval {
p CONST p CONST
EOS #=> "K's CONST" }
end end
end end
class K class K
CONST = "K's CONST" CONST = "K's CONST"
extend A extend A
f f
end end
2011 7 19 25
77. module_eval( ) module_eval
module A module A
CONST = "A's CONST" CONST = "A's CONST"
def f def f
class_eval <<-EOS class_eval {
p CONST p CONST
EOS #=> "K's CONST" } #=> "A's CONST"
end end
end end
class K class K
CONST = "K's CONST" CONST = "K's CONST"
extend A extend A
f f
end end
2011 7 19 25
78. module_eval( ) module_eval
module A module A
CONST = "A's CONST" CONST = "A's CONST"
def f def f
class_eval <<-EOS class_eval {
p CONST p CONST
EOS #=> "K's CONST" } #=> "A's CONST"
end K A Object end
end CONST
end
class K class K
CONST = "K's CONST" CONST = "K's CONST"
extend A extend A
f f
end end
2011 7 19 25
79. module_eval( ) module_eval
module A module A
CONST = "A's CONST" CONST = "A's CONST"
def f def f
class_eval <<-EOS class_eval {
p CONST p CONST
EOS #=> "K's CONST" } #=> "A's CONST"
end K A Object end A Object
end CONST
end CONST
K
class K class K
CONST = "K's CONST" CONST = "K's CONST"
extend A extend A
f f
end end
2011 7 19 25
81. module A
B = 42
end
A.class_eval do
def self.f
pB
end
end
A.f
2011 7 19 26
82. module A
B = 42
Ruby 1.9
end 42
A.class_eval do
def self.f
pB
end
end
A.f
2011 7 19 26
83. module A
B = 42
Ruby 1.9
end 42
A.class_eval do
def self.f Ruby 1.8.7
-e:8:in `f': uninitialized constant B (NameError)
pB
end
end
A.f
2011 7 19 26
84. module A
B = 42
y
Ruby 1.9
end
b
42
def self.f
pB
R
A.class_eval do
c u Ruby 1.8.7
-e:8:in `f': uninitialized constant B (NameError)
end
end
A.f
2011 7 19 26
85. #
abort when I pressed “About your
application’s environment” in welcome page.
➡ Welcome aboard
abort
2011 7 19 27
86. #
abort when I pressed “About your
application’s environment” in welcome page.
➡ Welcome aboard
abort
2011 7 19 27
87. #
abort when I pressed “About your
application’s environment” in welcome page.
➡ Welcome aboard
abort
2011 7 19 27
88. #
abort when I pressed “About your
application’s environment” in welcome page.
➡ Welcome aboard
abort
Assertion failed: ((b->flags & flags) == flags), function
rb_vm_prepare_block, file dispatcher.cpp, line 1406.
zsh: abort env VM_DISABLE_RBO=1 macruby -S rails server
2011 7 19 27