Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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,563 views

Published on

A presentation on Rubykaigi11

Published in: Technology
  • Be the first to comment

  • Be the first to like this

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

×