This is my presentation in RubyConf 2011, 30th Octobar 2011,New Orleans in the U.S.
Abstract:
MacRuby is an implementation of Ruby 1.9 that is built 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 the technical intricacies that I discovered along the way.
RubyConf 2011:
http://rubyconf.org/
How to Troubleshoot Apps for the Modern Connected Worker
MacRuby on Rails
1. MacRuby on Rails
Abstract
MacRuby is an implementation of Ruby 1.9 that is built 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
the technical intricacies that I discovered along the way.
This presentation was made possible by
17. My Company
• http://www.netlab.jp/
• Shimane, Japan
• Since 2001
➡ 10th Anniversary!
• 57 people
➡ 6 people are cRuby committers
• SI, Training, etc...
22. The NaCl Way
First, I want You to be happy.
Next, I want you to make Your
Family happy.
23. The NaCl Way
First, I want You to be happy.
Next, I want you to make Your
Family happy.
Finally, if you have more happiness
left, then please share it with Our
Company :)
25. The NaCl Way
(as I see it)
Employee
• First: Employee
26. The NaCl Way
(as I see it)
Employee's
Employee
Family
• First: Employee
• Next: Employee's Family
27. The NaCl Way
(as I see it)
Employee's
Employee Company
Family
• First: Employee
• Next: Employee's Family
• Finally: Company
28. The NaCl Way
(as I see it)
Employee's
Employee Company
Family
• First: Employee
• Next: Employee Family
• Finally: Company
29. The NaCl Way
(as I see it)
y
m !
e y!
v n
Employee's
lo a
Employee Company
Family
I p
•
•
First: Employee
c o m
Next: Employee Family
• Finally: Company
33. MacRuby 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 the
MacRuby on Rails
technical internals that I discovered along the
way.
38. MacRuby
• MacRuby is a unique blend of Ruby
1.9 and Objective-C.
• The goal of the MacRuby project is
to be 100% compatible
syntactically and behaviorally with
Ruby 1.9.
39. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
40. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
41. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
42. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
43. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
44. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
45. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
46. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
47. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
48. Ruby 1.9
Application
Ruby 1.9
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
OS
(Linux,Windows,Mac OS X,etc...)
49. MacRuby
Application
MacRuby
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
Mac OS X
50. MacRuby
Application
MacRuby
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
Mac OS X
51. MacRuby
Application
MacRuby
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
Mac OS X
52. MacRuby
Application
MacRuby
Built-in
Ruby VM
GC
Built-in Standard
Library Library
System libraries
Mac OS X
53. MacRuby
Application
MacRuby
Ruby VM AutoZone
Built-in
GC
Built-in Standard
Library Library
System libraries
Mac OS X
54. MacRuby
Application
MacRuby
Ruby VM AutoZone
Built-in
GC
Foundation
Built-in Standard
Library Library
System libraries
Mac OS X
55. MacRuby
Application
MacRuby
Ruby VM AutoZone
Built-in
GC
Foundation
Built-in Standard
Library Library
"kouji".transform("latin-hiragana")
System libraries
#=>
Mac OS X
56. MacRuby
Application
MacRuby
Ruby VM AutoZone
Built-in
GC
Foundation
Built-in Standard
Library Library
System libraries
Mac OS X
57. MacRuby
Application
MacRuby
Ruby VM AutoZone
Built-in
GC
Foundation
Built-in Standard
Library Library
System libraries
Mac OS X
58. MacRuby
Application
MacRuby
Ruby VM AutoZone
Built-in
GC
Foundation
Built-in Standard
Library Library
System libraries
Mac OS X
59. MacRuby
Application
MacRuby
Ruby VM AutoZone
Built-in
GC
Foundation
Built-in Standard
Library Library
System libraries
Mac OS X
60. MacRuby
Application
MacRuby
AutoZone
Generational
LLVM
Threaded GC
Built-in Standard
Library Library
Foundation
System libraries
Mac OS X
70. 7 months ago...
March 2011 in Japan
• I thought, "Does Rails work on MacRuby?".
• I managed to install Rails.
$ sudo macgem install rails
7 gems installed
$ sudo macgem install sqlite3-ruby
2 gems installed
72. Perhaps...
• I thought, "OK, it's installed, but surely
the Rails generators won't work...".
73. Perhaps...
• I thought, "OK, it's installed, but surely
the Rails generators won't work...".
• However, I managed to create a Rails project!?
$ macruby -S rails new demo
create
create README
...
create vendor/plugins
create vendor/plugins/.gitkeep
76. Are you kidding me?
• I tried to generate a scaffold...
• It failed. After all Rails didn't work on
MacRuby.
$ macruby -S rails generate scaffold Bookmark
title:string description:text url:string
...
Assertion failed: ((size_t)pos <
current_exceptions.size()), function
pop_current_exception, file vm.cpp, line 3434.
zsh: abort macruby -S rails generate scaffold
Bookmark title:string description:text
77. Are you kidding me?
• I tried to generate a scaffold...
• It failed. After all Rails didn't work on
MacRuby.
$ macruby -S rails generate scaffold Bookmark
title:string description:text url:string
$ macruby -S rails server
... ...
Assertion failed: ((size_t)pos < <
Assertion failed: ((size_t)pos
current_exceptions.size()), function
current_exceptions.size()), function
pop_current_exception, file file vm.cpp, line 3434.
pop_current_exception, vm.cpp, line 3434.
zsh:zsh: abort macruby -S rails generate scaffold
abort macruby -S rails server
Bookmark title:string description:text
78. My approach
Run Rails
SEGV or abort
Research
Coding
Run RubySpec
Run Rails
79. My approach
Run Rails
SEGV or abort
Research
Coding
Run RubySpec
Run Rails
80. My approach
Run Rails
SEGV or abort
Research
Coding
Run RubySpec
Run Rails
81. My approach
Run Rails
SEGV or abort
Research
Coding
Run RubySpec
Run Rails
82. My approach
Run Rails
SEGV or abort
Research
Coding
Run RubySpec
Run Rails
83. My approach
Run Rails
SEGV or abort
Research
Coding
Run RubySpec
Run Rails
84. Coding
My approach
Run RubySpec
Run Rails
SEGV or abort
Research
Coding
Run RubySpec
85. Coding
My approach
Run RubySpec
Run Rails
Required knowledge
SEGV or abort and technology
• cRuby
Research
• Objective-C
Coding • C++
Run RubySpec • LLVM
86. A couple of examples of
what I have fixed so far
87. #860 catch/throw
(in "old" MacRuby)
➡ MacRuby aborts if you use catch and throw inside
a rescue clause.
88. #860 catch/throw
(in "old" MacRuby)
➡ MacRuby aborts if you use catch and throw inside
a rescue clause.
01: begin
02: raise "A"
03: rescue
04: catch(:foo) { throw :foo }
05: end
89. #860 catch/throw
(in "old" MacRuby)
➡ MacRuby aborts if you use catch and throw inside
a rescue clause.
01: begin
02: raise "A"
03: rescue
04: catch(:foo) { throw :foo }
05: end
:ok
Assertion failed: ((size_t)pos < current_exceptions.size()),
function pop_current_exception, file vm.cpp, line 3448.
91. Exception Handling
(in MacRuby)
01: begin
02: raise "A"
03: rescue
04: begin
05: raise "B"
06: rescue
07: end
08: end
92. Exception Handling
(in MacRuby)
01: begin
02: raise "A"
03: rescue
04: begin
05: raise "B"
06: rescue
07: end
08: end
93. Exception Handling
(in MacRuby)
01: begin
02: raise "A"
03: rescue
04: begin
05: raise "B"
06: rescue
07: end
08: end
Exception Stack
94. Exception Handling
(in MacRuby)
01: begin
02: raise "A" push
03: rescue
04: begin
05: raise "B"
06: rescue
07: end
08: end "A"
Exception Stack
95. Exception Handling
(in MacRuby)
01: begin
02: raise "A" push
03: rescue
04: begin
05: raise "B"
06: rescue
07: end
08: end "A"
Exception Stack
96. Exception Handling
(in MacRuby)
01: begin
02: raise "A" push
03: rescue
04: begin
05: raise "B" push
06: rescue "B"
07: end
08: end "A"
Exception Stack
97. Exception Handling
(in MacRuby)
01: begin
02: raise "A" push
03: rescue
04: begin
05: raise "B" push
06: rescue "B"
07: end
08: end "A"
Exception Stack
98. Exception Handling
(in MacRuby)
01: begin
02: raise "A" push
03: rescue
04: begin
05: raise "B" push
06: rescue
07: end pop
08: end "A"
Exception Stack
99. Exception Handling
(in MacRuby)
01: begin
02: raise "A" push
03: rescue
04: begin
05: raise "B" push
06: rescue
07: end pop
08: end pop
Exception Stack
101. Exception Handling and catch / throw
(in MacRuby)
01: catch(:foo) {
02: begin
03: raise "A"
04: rescue
05: throw :foo
06: end
07: }
Exception Stack
102. Exception Handling and catch / throw
(in MacRuby)
01: catch(:foo) {
02: begin
03: raise "A"
04: rescue
05: throw :foo
06: end
07: }
Exception Stack
103. Exception Handling and catch / throw
(in MacRuby)
01: catch(:foo) {
02: begin
03: raise "A" push
04: rescue
05: throw :foo
06: end
07: }
"A"
Exception Stack
104. Exception Handling and catch / throw
(in MacRuby)
01: catch(:foo) {
02: begin
03: raise "A" push
04: rescue
05: throw :foo
06: end
07: }
"A"
Exception Stack
105. Exception Handling and catch / throw
(in MacRuby)
01: catch(:foo) {
02: begin
03: raise "A" push
04: rescue
05: throw :foo
06: end
07: }
"A"
Exception Stack
106. Exception Handling and catch / throw
(in MacRuby)
01: catch(:foo) {
02: begin
03: raise "A" push
04: rescue
05: throw :foo pop
06: end
07: }
Exception Stack
107. throw
(in "old " MacRuby)
Before being fixed(60723bf~), 'throw' always
popped the current Exception.
vm.cpp:4321:
VALUE
RoxorVM::ruby_throw(VALUE tag, VALUE value)
{
...
if (current_exception() != Qnil) {
pop_current_exception();
}
...
108. throw
(in "old " MacRuby)
Before being fixed(60723bf~), 'throw' always
popped the current Exception.
vm.cpp:4321:
VALUE
RoxorVM::ruby_throw(VALUE tag, VALUE value)
{
...
if (current_exception() != Qnil) {
pop_current_exception();
}
...
109. throw
(in "old " MacRuby)
Before being fixed(60723bf~), 'throw' always
popped the current Exception.
vm.cpp:4321:
VALUE
RoxorVM::ruby_throw(VALUE tag, VALUE value)
{
...
if (current_exception() != Qnil) {
pop_current_exception();
}
...
110. #860 catch/throw
(in "old" MacRuby)
01: begin
02: raise "A"
03: rescue
04: catch(:foo) { throw :foo }
05: end
Exception Stack
111. #860 catch/throw
(in "old" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo }
05: end
"A"
Exception Stack
112. #860 catch/throw
(in "old" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo }
05: end
"A"
Exception Stack
113. #860 catch/throw
(in "old" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo } pop
05: end
Exception Stack
114. #860 catch/throw
(in "old" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo } pop
05: end pop
Exception Stack
115. #860 catch/throw
(in "old" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo } pop
05: end pop
t ! !
o r
A b Exception Stack
116. How to fix
(in "new" MacRuby)
01: begin
02: raise "A"
03: rescue
04: catch(:foo) { throw :foo }
05: end
Exception Stack
117. How to fix
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo }
05: end
"A"
Exception Stack
118. How to fix
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo }
store
05: end
"A"
Exception Stack
119. How to fix
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo }
store
05: end
"A"
Exception Stack
120. How to fix
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { throw :foo }
store
05: end pop
Exception Stack
121. How to fix
(in "new" MacRuby)
In the new implementation, MacRuby only pops
exceptions when necessary (60723bf)
vm.cpp:4318:
VALUE
RoxorVM::ruby_throw(VALUE tag, VALUE value)
{
...
while (catch_ptr->current_exception !=
current_exception()) {
pop_current_exception();
}
...
122. How to fix
(in "new" MacRuby)
In the new implementation, MacRuby only pops
exceptions when necessary (60723bf)
vm.cpp:4318:
VALUE
RoxorVM::ruby_throw(VALUE tag, VALUE value)
{
...
while (catch_ptr->current_exception !=
current_exception()) {
pop_current_exception();
}
...
123. How to fix
(in "new" MacRuby)
In the new implementation, MacRuby only pops
exceptions when necessary (60723bf)
vm.cpp:4318:
VALUE
RoxorVM::ruby_throw(VALUE tag, VALUE value)
{
...
while (catch_ptr->current_exception !=
current_exception()) {
pop_current_exception();
}
...
124. #860 Fixed
(in "new" MacRuby)
01: begin
02: raise "A"
03: rescue
04: catch(:foo) {
05: begin
06: raise "B"
07: rescue
08: throw :foo
09: end
10: }
11: end Exception Stack
125. #860 Fixed
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { store
05: begin
06: raise "B"
07: rescue
08: throw :foo
09: end "A"
10: }
11: end Exception Stack
126. #860 Fixed
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { store
05: begin
06: raise "B" push
07: rescue "B"
08: throw :foo
09: end "A"
10: }
11: end Exception Stack
127. #860 Fixed
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { store
05: begin
06: raise "B" push
07: rescue "B"
08: throw :foo
09: end "A"
10: }
11: end Exception Stack
128. #860 Fixed
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { store
05: begin
06: raise "B" push
07: rescue
08: throw :foo pop
09: end "A"
10: }
11: end Exception Stack
129. #860 Fixed
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { store
05: begin
06: raise "B" push
07: rescue
08: throw :foo pop
09: end "A"
10: }
11: end Exception Stack
130. #860 Fixed
(in "new" MacRuby)
01: begin
02: raise "A" push
03: rescue
04: catch(:foo) { store
05: begin
06: raise "B" push
07: rescue
08: throw :foo pop
09: end
10: }
11: end pop Exception Stack
131. #1192 Constant Lookup
➡ MacRuby failed to correctly look up
constants in a number of situations when
you used module_eval and class_eval.
132. #1192 Constant Lookup
➡ MacRuby failed to correctly look up
constants in a number of situations when
you used module_eval and class_eval.
module A
B = 10
Object.class_eval { B }
end
133. #1192 Constant Lookup
➡ MacRuby failed to correctly look up
constants in a number of situations when
you used module_eval and class_eval.
module A
B = 10
Object.class_eval { B }
end
reduction.rb:3:in `block': uninitialized constant
B (NameError)
134. #1192 Constant Lookup
➡ MacRuby failed to correctly look up
constants in a number of situations when
you used module_eval and class_eval.
module A cRuby
B = 10
Object.class_eval { B }
end
reduction.rb:3:in `block': uninitialized constant
B (NameError)
135. #1192 Constant Lookup
➡ MacRuby failed to correctly look up
constants in a number of situations when
you used module_eval and class_eval.
module A
BMacRuby
= 10
Object.class_eval { B }
end
reduction.rb:3:in `block': uninitialized constant
B (NameError)
137. Constant Lookup
(in cRuby)
1: module A
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
138. Constant Lookup
(in cRuby)
1: module A
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
139. Constant Lookup
(in cRuby)
1: module A
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
140. Constant Lookup
(in cRuby)
1: module A
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
141. Constant Lookup
(in cRuby)
1: module A
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
142. Constant Lookup
(in cRuby)
1: module A
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
143. Constant Lookup
(in cRuby)
1: module A Lexical Scope
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
144. Constant Lookup
(in cRuby)
1: module A Lexical Scope
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
Lookup
7: end
ons tant
8: end exi
L cal C
145. Constant Lookup
(in "old" MacRuby)
MacRuby had not implemented Lexical
Constant Lookup.
1: module A
2: module B
3: CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
146. Constant Lookup
(in "old" MacRuby)
MacRuby had not implemented Lexical
Constant Lookup.
1: module A
2: module B
3: MacRuby
CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
147. Constant Lookup
(in "old" MacRuby)
MacRuby had not implemented Lexical
Constant Lookup.
1: module A
2: module B
3: MacRuby
CONST = "B’s Const"
4: module ::A
5: p CONST
6: end
7: end
8: end
-e:5:in `block': uninitialized constant A::CONST (NameError)
149. Constant Lookup is complex
(in cRuby)
class_eval(&Block) class_eval(String)
01: module A 01: module A
02: CONST = "A's CONST" 02: CONST = "A's CONST"
03: def f() 03: def f()
04: class_eval { 04: class_eval <<-EOS
05: p CONST 05: p CONST
06: } 06: EOS
07: end 07: end
08: end 08: end
09: 09:
10: class K 10: class K
11: CONST = "K's CONST" 11: CONST = "K's CONST"
12: extend A 12: extend A
13: f() 13: f()
14: end 14: end
150. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
151. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
152. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
153. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
154. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
155. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
156. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
157. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
158. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
159. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
160. class_eval(&Block)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
161. class_eval(&Block)
01: module A Lexical Scope
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: }
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
162. class_eval(&Block)
01: module A Lexical Scope
02: CONST = "A's CONST"
03: def f()
04: class_eval {
05: p CONST
06: } ON ST"
07: end "A's C
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
163. class_eval(String)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval <<-EOS
05: p CONST
06: EOS
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
164. class_eval(String)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval <<-EOS
05: p CONST
06: EOS
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
165. class_eval(String)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval <<-EOS
05: p CONST
06: EOS
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
166. class_eval(String)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval <<-EOS
05: p CONST
06: EOS
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
167. class_eval(String)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval <<-EOS
05: p CONST
06: EOS
07: end
08: end
09:
10: class K
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
168. class_eval(String)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval <<-EOS
05: p CONST
06: EOS
07: end
08: end
09:
10: class K Dynamic Scope
11: CONST = "K's CONST"
12: extend A
13: f()
14: end
169. class_eval(String)
01: module A
02: CONST = "A's CONST"
03: def f()
04: class_eval <<-EOS
05: p CONST
06: EOS
07: end
08: end
09:
10: class K Dynamic Scope
11: CONST = "K's CONST"
12: extend A
13: f() ON ST"
14: end "K's C
170. Constant Lookup is complex
(in cRuby)
class_eval(&Block) class_eval(String)
01: module A Lexical Scope 01: module A
02: CONST = "A's CONST" 02: CONST = "A's CONST"
03: def f() 03: def f()
04: class_eval { 04: class_eval <<-EOS
05: p CONST 05: p CONST
06: }
ST" 06: EOS
07: end
"A's CON 07: end
08: end 08: end
09: 09:
10: class K 10: class K Dynamic Scope
11: CONST = "K's CONST" 11: CONST = "K's CONST"
12: extend A 12: extend A
13: f() 13: f()
ON ST"
14: end 14: end " K's C
172. I somehow managed to fix this
(in MacRuby)
• Three attempts to get it right.
173. I somehow managed to fix this
(in MacRuby)
• Three attempts to get it right.
• More than 3000 lines of code changed.
174. I somehow managed to fix this
(in MacRuby)
• Three attempts to get it right.
• More than 3000 lines of code changed.
21 Apr 2011 15:24 Laurent S.
it's official,
kouji is the hero of th e day/week/month/...?
his patch seem s to fix remaining lexical
const lookup bugs :)
176. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
177. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
178. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
179. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
180. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
181. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
182. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
183. A very complex bug
(in "new" MacRuby)
01: module A
02: B = 42
03: end
04: Lexical
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
184. A very complex bug
(in "new" MacRuby)
CAUTION
'class_eval' does not add it's own receiver
01: module A
(A) 02: theBconstant lookup scope.
to = 42
03: end
04: Lexical
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
185. A very complex bug
(in cRuby)
01: module A
02: B = 42
03: end
04:
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
186. A very complex bug
(in cRuby)
01: module A
02: B = 42
end uby 1.9
03: R
04: ➡42
05: A.class_eval do
06: def self.f
07: p B
08: end
09: end
10:
11: A.f
187. A very complex bug
(in cRuby)
01: module A
02: B = 42
03: end uby 1.9
R
04: ➡ 42
05: A.class_eval do
06: def self.f
07: p B eError)
tB(Nam
nstan
08: end
09: .8.7
1 end ialized co
R u10: `f': uninit
by
-e :8:in
➡11: A.f
188. A very complex bug
(in cRuby)
01: module A
02: B = 42
03: end uby 1.9
R
04:
A cR ➡ 42
uby's
05: A.class_eval do
06: def self.f
ror)
07:
08:
09: .8.7
end Bug
p B
d constantB(NameEr
R
1 end
u10: `f': uninit
by ialize
-e :8:in
➡11: A.f
189. Demo
$ rails new demo
$ rails generate scaffold ...
$ rails server
190. #1390 rb_vm_prepare_block
➡ Abort if the "About your application’s
environment" is link is clicked.
CLICK!
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
197. Conclusion
• MacRuby
➡MacRuby is a unique blend of Ruby 1.9 and
Objective-C.
➡The goal is to be 100% compatible with Ruby 1.9.
198. Conclusion
• MacRuby
➡MacRuby is a unique blend of Ruby 1.9 and
Objective-C.
➡The goal is to be 100% compatible with Ruby 1.9.
• MacRuby on Rails
➡We're now able to show the default Rails welcome
page.
➡But there is still a lot to do.
204. Q &A
• If you have a question, please ask me, but if
possible please speak slowly.
• or contact @takaokouji_en by Twitter
• or send e-mail to MacRuby ML