fork download
  1. class Door
  2. def initialize; @closed = true; @knob = Knob.new(self) end
  3. def knob; @knob end
  4. def is_open; !is_close end
  5. def is_close; @closed end
  6. def can_be_open; !@closed or knob.is_latched_off end
  7. def pull; @closed = true; @knob.unturn end
  8. def push; @closed = false if can_be_open end
  9. end
  10.  
  11. class Knob
  12. def initialize(door); @door = door; @latched = true end
  13. def is_latched_off; !@latched end
  14. def turn; @latched = false end
  15. def unturn; @latched = true if @door.is_close end
  16. end
  17.  
  18. door1 = Door.new
  19. print "door1 is a Door...\n"
  20. door1.knob.turn
  21. print "door1.knob.turn; door1.can_be_open => #{door1.can_be_open}\n"
  22. door1.knob.unturn
  23. print "door1.knob.unturn; door1.can_be_open => #{door1.can_be_open}\n"
  24. door1.push
  25. print "door1.push; door1.is_open => #{door1.is_open}\n"
  26. door1.knob.turn; door1.push
  27. print "door1.knob.turn; door1.push; door1.is_open => #{door1.is_open}\n"
  28. door1.pull
  29. print "door1.pull; door1.is_close => #{door1.is_close}\n"
  30. print "door1.can_be_open => #{door1.can_be_open}\n\n"
  31.  
  32.  
  33. class DoorWithCloser < Door
  34. attr_reader :delay_sec
  35.  
  36. def initialize; super; @delay_sec = 0.3 end
  37.  
  38. def exec_delayed_pull
  39. if is_open then
  40. @delayed_pull.kill if @delayed_pull
  41. @delayed_pull = Thread.start{ sleep(@delay_sec); pull }
  42. sleep(0)
  43. end
  44. end
  45.  
  46. def delay_sec=(num)
  47. @delay_sec = num
  48. exec_delayed_pull
  49. end
  50.  
  51. def push
  52. super
  53. exec_delayed_pull
  54. end
  55. end
  56.  
  57. door2 = DoorWithCloser.new
  58. print "door2 is a DoorWithCloser with #{door2.delay_sec} seconds delay ...\n"
  59. door2.knob.turn; door2.push
  60. print "door2.knob.turn; door2.push; door2.is_open => #{door2.is_open}\n"
  61. print "0.1 second after"
  62. sleep(0.1)
  63. print ", door2.is_open => #{door2.is_open}\n"
  64. print "0.4 seconds after"
  65. sleep(0.3)
  66. print ", door2.is_close => #{door2.is_close}\n"
  67. door2.knob.turn; door2.push; door2.delay_sec = 0.6
  68. print "door2.knob.turn; door2.push; door2_delay_sec = 0.6; door2.is_open => #{door2.is_open}\n"
  69. print "0.4 seconds after"
  70. sleep(0.4)
  71. print ", door2.is_close => #{door2.is_close}\n"
  72. print "0.7 seconds after"
  73. sleep(0.3)
  74. print ", door2.is_close => #{door2.is_close}\n\n"
  75.  
  76.  
  77.  
  78. module DoorStopper
  79. def initialize; super; @stoppered = false end
  80. def is_stoppered; @stoppered end
  81. def be_stoppered_off; @stoppered = false end
  82. def be_stoppered_on; @stoppered = true end
  83. def pull; super unless is_stoppered end
  84. def push; @stoppered = false; super end
  85. end
  86.  
  87. class DoorWithStopper < Door
  88. include DoorStopper
  89. end
  90.  
  91. door3 = DoorWithStopper.new
  92. print "door3 is a DoorWithStopper...\n"
  93. door3.knob.turn; door3.push
  94. print "door3.knob.turn; door3.push; door3.is_open => #{door3.is_open}\n"
  95. door3.be_stoppered_on; door3.pull
  96. print "door3.be_stoppered_on; door3.pull; door3.is_close => #{door3.is_close}\n"
  97. door3.be_stoppered_off; door3.pull
  98. print "door3.be_stoppered_off; door3.pull; door3.is_close => #{door3.is_close}\n"
  99. door3.knob.turn; door3.push
  100. print "door3.knob.turn; door3.push; door3.is_open => #{door3.is_open}\n"
  101. door3.be_stoppered_on; door3.pull
  102. print "door3.be_stoppered_on; door3.pull; door3.is_close => #{door3.is_close}\n"
  103. door3.push; door3.pull
  104. print "door3.push; door3.pull; door3.is_close => #{door3.is_close}\n\n";
  105.  
  106. class DoorWithStopperCloser < DoorWithCloser
  107. include DoorStopper
  108. def be_stoppered_off; super; exec_delayed_pull end
  109. end
  110.  
  111. door4 = DoorWithStopperCloser.new
  112. print "door4 is a DoorWithStopperCloser with #{door4.delay_sec} seconds delay ...\n"
  113. door4.knob.turn; door4.push
  114. print "door4.knob.turn; door4.push; door4.is_open => #{door4.is_open}\n"
  115. door4.be_stoppered_on
  116. print "door4.be_stoppered_on then 0.4 seconds after"
  117. sleep(0.4)
  118. print ", door4.is_open=> #{door4.is_open}\n"
  119. door4.be_stoppered_off
  120. print "door4.be_stoppered_off then 0.4 seconds after"
  121. sleep(0.4); door4.push
  122. print ", door4.is_close => #{door4.is_close}\n"
  123. door4.knob.turn; door4.push
  124. print "door4.knob.turn; door4.push; door4.is_open => #{door4.is_open}\n"
  125. door4.be_stoppered_on
  126. print "door4.be_stoppered_on then 0.4 seconds after"
  127. sleep(0.4)
  128. print ", door4.is_open=> #{door4.is_open}\n"
  129. door4.push
  130. print "door4.push then 0.4 seconds after"
  131. sleep(0.4); door4.push
  132. print ", door4.is_close => #{door4.is_close}\n"
Success #stdin #stdout 0s 98368KB
stdin
Standard input is empty
stdout
door1 is a Door...
door1.knob.turn; door1.can_be_open => true
door1.knob.unturn; door1.can_be_open => false
door1.push; door1.is_open => false
door1.knob.turn; door1.push; door1.is_open => true
door1.pull; door1.is_close => true
door1.can_be_open => false

door2 is a DoorWithCloser with 0.3 seconds delay ...
door2.knob.turn; door2.push; door2.is_open => true
0.1 second after, door2.is_open => true
0.4 seconds after, door2.is_close => true
door2.knob.turn; door2.push; door2_delay_sec = 0.6; door2.is_open => true
0.4 seconds after, door2.is_close => false
0.7 seconds after, door2.is_close => true

door3 is a DoorWithStopper...
door3.knob.turn; door3.push; door3.is_open => true
door3.be_stoppered_on; door3.pull; door3.is_close => false
door3.be_stoppered_off; door3.pull; door3.is_close => true
door3.knob.turn; door3.push; door3.is_open => true
door3.be_stoppered_on; door3.pull; door3.is_close => false
door3.push; door3.pull; door3.is_close => true

door4 is a DoorWithStopperCloser with 0.3 seconds delay ...
door4.knob.turn; door4.push; door4.is_open => true
door4.be_stoppered_on then 0.4 seconds after, door4.is_open=> true
door4.be_stoppered_off then 0.4 seconds after, door4.is_close => true
door4.knob.turn; door4.push; door4.is_open => true
door4.be_stoppered_on then 0.4 seconds after, door4.is_open=> true
door4.push then 0.4 seconds after, door4.is_close => true