Method Shelters :Another Way to Resolve ClassExtension ConflictsClassboxes でも Refinements でもない別のやり方                    Shu...
What I talk about todayOpen Class causes conflicts of methodsMethod Shelters resolve it!
% whoami Shumpei Akai / 赤井駿平 @flexfrank Ph.D. Student / 学生(博士課程)    ◦ 東工大の千葉研    ◦ Programming Languages and Moduraliza...
Open Class Ruby’s one of the important features You can (re)define methods in existing  classes    ◦ including Object, I...
in open-uri   open-uri redefines “open” method    ◦ It accepts URI       open("http://penguindrum.jp/"){|f|f.read}       ...
in Ruby on Rails   ActiveSupport adds various convenient    methods to core classes    ◦ e.g.    10.megabytes # => 104857...
Or Monkey   Patching
Problem of Open Class Methods may conflict When One library adds a method    ◦ and another library adds a method with th...
Method conflicts   I encountered about five years ago    ◦ Ruby on Rails and flvtool added a method to      String    ◦ t...
Another example of conflicts   “mathn” redefines the “Integer#/”    ◦ returns a Rational object    ◦ Ordinary code expect...
Existing Solutions   Several module systems are proposed to    resolve conflicts    ◦   Selector namespaces (for Smalltal...
Refinements   Proposed by Shugo Maeda [ruby-core:33322]                           class Foo       module MathN          u...
Refinements (cont.)   Refinements changes behavior of    methods in a lexical scope    ◦ methods defined by Refinements a...
Classboxes   You might have known via matz’s diary
Classboxes A classbox restrict the scope of methods A classbox can import a class in another  classbox    ◦ You can use ...
Classboxes Cited from “Classbox/J: Controlling the Scope of Change in Java”
The Problem in Classboxes   Importing overwrites internally used    classes    ◦ Importing causes another conflict
The Problem in     Classboxes    Redefines                            Original   Integer#div                           Int...
I need another module system   A new module should:    ◦ have local rebinding    ◦ provide a way to resolve conflicts cau...
Method Shelters
Key conceptHide your methodsHide your imports
What is a method shelter   A method shelter is a module which    provides a scope of methods    ◦ define methods in a met...
A Code with Method Sheltersshelter :MathN do class Fixnum # fixed size integer in Ruby  def /(x)    Rational(self,x)  end ...
What conforms a method shelter   A method shelter is separated into tow    parts    ◦ An exposed chamber and a hidden cha...
Exposed Chambers                   S0                                        - Obj#m0 for public API Exposed methods    ...
Hidden chamber                   S0                                      - Obj#m1   - Obj#m0 for internally used  methods...
Global Methods   Ordinal methods not in shelters    ◦ Callable from any shelter    ◦ Global methods can call methods in a...
No Ambiguity   If 2+ methods are found in imported    shelters                 S3                                  - C#m0...
Syntax I don’t want to edit parse.y define methods in a block    shelter :ShelterName do     class Foo      def hoge # <...
Syntax: Importshelter :ShelterName do  import :AnotherShelterNameend
Syntax: hide   “hide” method switches a chamber    ◦ do def or import below “hide”shelter :ShelterName do  # exposed cham...
Evaluate   Evaluate within a shelter       shelter_eval :ShelterName do         #shelter is enabled       end
Method Lookup Algorithm 1. look up hidden-chamber 2. look up exposed-chamber 3. look up global methods   If not found,...
8                                   3             7               6           2                                 5   1     ...
Found!                          1Start        Global
Implementation Based on Ruby 1.9.2 Add one implicit argument to method:    ◦ A node of method shelter tree
Optimization: Method Cache   Shelter node cache    ◦ Caches method entry in a node of shelter   Extend inline cache    ◦...
Performance: empty methods   Call a empty method 10,000,000 times    ◦ Less than 5% overhead when shelters are      used
Performance: Fibonacci   fib(33) in a method shelter    ◦ Up to 20% overhead
Performance: Ruby on Rails   Enabled in an action method    ◦ Numeric#/.*bytes?/ methods are in a shelter   In the actio...
Performance:             Ruby on Rails (result)              4% overhead on production env.              50% on developm...
Cache hit ratio on rails   Count shelter’s cache hit
Performance: tDiary 3.0.1   defined    String#to_a, String#each, String#method_    missing in a shelter    ◦ These are us...
Why shelter made tDiary fast String#method_missing issue “require” calls its arg’s to_path method if  defined    ◦ If ar...
Other Usage:protect optimized methods   In ruby, + - * / … are optimized    ◦ only if they are not redefined    ◦ Redefin...
Other Usage:shelter-private accessor Ruby has no private instance variables A method shelter can mimic private ivars    ...
class Module def shelter_accessor(name)  define_method name do    ivname=get_unique_name(name)    self.instance_variable_g...
Conclusion Open class is dangerous Method shelters resolving conflicts    ◦ With hidden methods, hiddenly importing   I...
Questions?
時間が余ったら
Global
   In my lookup algorithm,    ◦ Shelter must have up to one parent For simpler semantics For efficient implementation
before         C     B         A
after        C’       C’’        B             A
Upcoming SlideShare
Loading in …5
×

Method Shelters : Another Way to Resolve Class Extension Conflicts

3,518 views

Published on

A presentation on Rubykaigi11

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
3,518
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Method Shelters : Another Way to Resolve Class Extension Conflicts

  1. 1. Method Shelters :Another Way to Resolve ClassExtension ConflictsClassboxes でも Refinements でもない別のやり方 Shumpei Akai / 赤井駿平 @flexfrank
  2. 2. What I talk about todayOpen Class causes conflicts of methodsMethod Shelters resolve it!
  3. 3. % whoami Shumpei Akai / 赤井駿平 @flexfrank Ph.D. Student / 学生(博士課程) ◦ 東工大の千葉研 ◦ Programming Languages and Moduralization ◦ プログラミング言語とモジュール化 Today’s topic is my current research
  4. 4. Open Class Ruby’s one of the important features You can (re)define methods in existing classes ◦ including Object, Integer, Array, … Frequently used in Ruby world
  5. 5. in open-uri open-uri redefines “open” method ◦ It accepts URI open("http://penguindrum.jp/"){|f|f.read} # => Errno::ENOENT: No such file or directory require "open-uri” open("http://penguindrum.jp/"){|f|f.read} # => "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1- transitional.dtd”…”
  6. 6. in Ruby on Rails ActiveSupport adds various convenient methods to core classes ◦ e.g. 10.megabytes # => 10485760 1.day.ago # => Sat Jul 16 16:15:00 +0900 2011 "survival strategy".pluralize #=> "survival strategies"
  7. 7. Or Monkey Patching
  8. 8. Problem of Open Class Methods may conflict When One library adds a method ◦ and another library adds a method with the same name in the same class The method defined first is vanished! ◦ depends on the order of “require” ◦ Confusing!
  9. 9. Method conflicts I encountered about five years ago ◦ Ruby on Rails and flvtool added a method to String ◦ they used String as binary/array of int Difficult to collaborate these two libraries ◦ I separated processes ◦ communicating via dRuby
  10. 10. Another example of conflicts “mathn” redefines the “Integer#/” ◦ returns a Rational object ◦ Ordinary code expects “/” returns a integer  Programs get broken
  11. 11. Existing Solutions Several module systems are proposed to resolve conflicts ◦ Selector namespaces (for Smalltalk) ◦ Classboxes (for Smalltalk and Java) ◦ Refinements (for Ruby) ◦ …
  12. 12. Refinements Proposed by Shugo Maeda [ruby-core:33322] class Foo module MathN using MathN refine Fixnum do def foo def /(other) p1/2 quo(other) end end end end end f = Foo.new f.foo #=> (1/2) p1/2
  13. 13. Refinements (cont.) Refinements changes behavior of methods in a lexical scope ◦ methods defined by Refinements are not enabled in indirectly called methods ◦ No local rebinding I need local rebinding ◦ e.g. scoped monkey patching
  14. 14. Classboxes You might have known via matz’s diary
  15. 15. Classboxes A classbox restrict the scope of methods A classbox can import a class in another classbox ◦ You can use an imported class ◦ You can add/redefine methods to the imported class ◦ A redefined method can be called from the imported class  Local rebinding property
  16. 16. Classboxes Cited from “Classbox/J: Controlling the Scope of Change in Java”
  17. 17. The Problem in Classboxes Importing overwrites internally used classes ◦ Importing causes another conflict
  18. 18. The Problem in Classboxes Redefines Original Integer#div IntegerUses redefined Use original Integer#div Integerreturns rational Oops! returns integer
  19. 19. I need another module system A new module should: ◦ have local rebinding ◦ provide a way to resolve conflicts cause by importing ◦ not depends on the order of load
  20. 20. Method Shelters
  21. 21. Key conceptHide your methodsHide your imports
  22. 22. What is a method shelter A method shelter is a module which provides a scope of methods ◦ define methods in a method shelter ◦ import other method shelters  You can call methods in the imported shelter  You can call methods in the shelter which is importing the current shelter  for local rebinding call importee call importer
  23. 23. A Code with Method Sheltersshelter :MathN do class Fixnum # fixed size integer in Ruby def /(x) Rational(self,x) end endendshelter :Average do class Array def avg sum = self.inject(0){|r,i|r+i} sum / self.size end end hide import :MathNend
  24. 24. What conforms a method shelter A method shelter is separated into tow parts ◦ An exposed chamber and a hidden chamber ◦ in order to protect internally used methods ◦ Each chamber can define methods and import - Exposed - Hidden
  25. 25. Exposed Chambers S0 - Obj#m0 for public API Exposed methods ◦ Visible from importer ◦ Importer can call or redefine exposed S1 methods Exposedly import ◦ Transitive importing ◦ Imported methods are S2 also visible from importer
  26. 26. Hidden chamber S0 - Obj#m1 - Obj#m0 for internally used methods Hidden method S1 ◦ invisible in importing shelter Hiddenly import S2 ◦ Imported methods are not exposed
  27. 27. Global Methods Ordinal methods not in shelters ◦ Callable from any shelter ◦ Global methods can call methods in a shelter if the caller is in the shelter Global - Obj#g0 S0 obj.g0()
  28. 28. No Ambiguity If 2+ methods are found in imported shelters S3 - C#m0 ◦ Error! S1 S2 - C#m0 S0 Error!
  29. 29. Syntax I don’t want to edit parse.y define methods in a block shelter :ShelterName do class Foo def hoge # <- defined in the method shelter end end end
  30. 30. Syntax: Importshelter :ShelterName do import :AnotherShelterNameend
  31. 31. Syntax: hide “hide” method switches a chamber ◦ do def or import below “hide”shelter :ShelterName do # exposed chamber hide # hidden chamberend
  32. 32. Evaluate Evaluate within a shelter shelter_eval :ShelterName do #shelter is enabled end
  33. 33. Method Lookup Algorithm 1. look up hidden-chamber 2. look up exposed-chamber 3. look up global methods If not found, go to superclass
  34. 34. 8 3 7 6 2 5 1 startGlobal 9 4
  35. 35. Found! 1Start Global
  36. 36. Implementation Based on Ruby 1.9.2 Add one implicit argument to method: ◦ A node of method shelter tree
  37. 37. Optimization: Method Cache Shelter node cache ◦ Caches method entry in a node of shelter Extend inline cache ◦ Size of an inline cache : 3 word -> 4word (per method call) ◦ Stores the found shelter node
  38. 38. Performance: empty methods Call a empty method 10,000,000 times ◦ Less than 5% overhead when shelters are used
  39. 39. Performance: Fibonacci fib(33) in a method shelter ◦ Up to 20% overhead
  40. 40. Performance: Ruby on Rails Enabled in an action method ◦ Numeric#/.*bytes?/ methods are in a shelter In the action ◦ 1. Call one method in shelter ◦ 2. One access to SQLite via ActiveRecord on WEBRick Rails3
  41. 41. Performance: Ruby on Rails (result)  4% overhead on production env.  50% on development ◦ Method caches are invalidated per req.productiondevelopment
  42. 42. Cache hit ratio on rails Count shelter’s cache hit
  43. 43. Performance: tDiary 3.0.1 defined String#to_a, String#each, String#method_ missing in a shelter ◦ These are used for compatibility of 1.8 & 1.9 Ran on CGI with apache Method shelter improved performance !! ◦ Why?
  44. 44. Why shelter made tDiary fast String#method_missing issue “require” calls its arg’s to_path method if defined ◦ If arg’s method_missing is defined, try to call it ◦ String#method_missing slows “require” Method shelter restrict its negative effect
  45. 45. Other Usage:protect optimized methods In ruby, + - * / … are optimized ◦ only if they are not redefined ◦ Redefinition slows programs Method shelters can confine effect of redefinition Method shelter can improve performance
  46. 46. Other Usage:shelter-private accessor Ruby has no private instance variables A method shelter can mimic private ivars ◦ by generating unique name ◦ Accessible within the defined shelter and visible shelters
  47. 47. class Module def shelter_accessor(name) define_method name do ivname=get_unique_name(name) self.instance_variable_get(ivname) end define_method( (name.to_s+"=").to_sym) do|val| ivname= get_unique_name(name) self.instance_variable_set(ivname,val) end endend
  48. 48. Conclusion Open class is dangerous Method shelters resolving conflicts ◦ With hidden methods, hiddenly importing I implemented in Ruby ◦ Not so slow (個人的な感覚) For more details or the source code, ◦ wait for the acceptance of my paper  Deadline: 2.days.since
  49. 49. Questions?
  50. 50. 時間が余ったら
  51. 51. Global
  52. 52.  In my lookup algorithm, ◦ Shelter must have up to one parent For simpler semantics For efficient implementation
  53. 53. before C B A
  54. 54. after C’ C’’ B A

×