Ruby/Language Basics/Modules Creation
Материал из Wiki.crossplatform.ru
Abstract method in a module
module Complaint def gripe voice("A") end def faint_praise voice("B") end def voice(complaint_text) raise NotImplementedError, "#{self.class} included the Complaint module but didn"t define voice!" end end class MyComplaint include Complaint end MyComplaint.new.gripe # NotImplementedError: MyComplaint included the Complaint module # but didn"t define voice!
access methods inside classes inside modules with Ruby scope resolution operator (::)
module Mathematics class Adder def Adder.add(operand_one, operand_two) return operand_one + operand_two end end end puts "2 + 3 = " + Mathematics::Adder.add(2, 3).to_s
Avoiding Naming Collisions with Namespaces
module StringTheory class String def initialize(length=10**-33) @length = length end end end String.new # => "" StringTheory::String.new module StringTheory2 RubyString = String class String def initialize(length=10**-33) @length = length end end RubyString.new("This is a built-in string, not a StringTheory2::String") end # => "This is a built-in string, not a StringTheory2::String"
Creating Modules
# To create a module, you use the module keyword. # You can place modules and the code that uses them in the same file, or break them out among separate files. #file: mathematics.rb. module Mathematics def Mathematics.add(operand_one, operand_two) return operand_one + operand_two end end file: sentence.rb module Sentence def Sentence.add(word_one, word_two) return word_one + "" + word_two end end file: ModuleTest.rb require "mathematics" require "sentence" puts "2 + 3 = " + Mathematics.add(2, 3).to_s
how to create a module and then include it in a class.
File: mixin.rb #!/usr/bin/env ruby module Dice # virtual roll of a pair of dice def roll r_1 = rand(6); r_2 = rand(6) r1 = r_1>0?r_1:1; r2 = r_2>0?r_2:6 total = r1+r2 printf( "You rolled %d and %d (%d).\n", r1, r2, total ) total end end class Game include Dice end g = Game.new g.roll
Initializing Instance Variables Defined by a Module
module Timeable attr_reader :time_created def initialize @time_created = Time.now end def age #in seconds Time.now - @time_created end end class Character include Timeable attr_reader :name def initialize( name ) @name = name super() #calls Timeable"s initialize end end c = Character.new "Fred" c.time_created # => Mon Mar 27 18:34:31 EST 2006 p Character.ancestors # => [Character, Timeable, Object, Kernel]
Involve demonstrating two classes with the same name, but in different modules
module ToolBox class Ruler attr_accessor :length end end module Country class Ruler attr_accessor :name end end a = ToolBox::Ruler.new a.length = 50 b = Country::Ruler.new b.name = "Ghengis Khan from Moskau"
Modules and Namespaces
Class.superclass # => Module puts Math.class # => Module puts Math.new
Modules provide a structure to collect Ruby classes, methods, and constants into a single, separately named and defined unit.
# Modules solve conflicts by providing namespaces that can contain any number of classes, # methods, and constants, and allow you to address them directly.: module NumberStuff def NumberStuff.random rand(1000000) end end module LetterStuff def LetterStuff.random (rand(26) + 65).chr end end puts NumberStuff.random puts LetterStuff.random
prefixed with the module name you can call the method from anywhere, as is the case with the Math module.
#!/usr/bin/env ruby module Binary def Binary.to_bin( num ) bin = sprintf("%08b", num) end end Binary.to_bin( 123 ) # => "01111011"
Print all classes (excluding exceptions)
puts Module.constants.sort.select {|x| c = eval(x.to_s) c.is_a? Class and not c.ancestors.include? Exception }
Print all exceptions
puts Module.constants.sort.select {|x| c = eval(x.to_s) c.instance_of? Class and c.ancestors.include? Exception }
Print all modules (excluding classes)
puts Module.constants.sort.select {|x| eval(x.to_s).instance_of? Module}
require the file containing the module, and then it would work (again, require is expecting a name in the load path).
module Dice # virtual roll of a pair of dice def roll r_1 = rand(6); r_2 = rand(6) r1 = r_1>0?r_1:1; r2 = r_2>0?r_2:6 total = r1+r2 printf( "You rolled %d and %d (%d).\n", r1, r2, total ) total end end File: game.rb #!/usr/bin/env ruby require "dice" class Game include Dice end g = Game.new g.roll
store classes inside modules.
module Mathematics class Adder def Adder.add(operand_one, operand_two) return operand_one + operand_two end end end
Use remove_const to delete a constant definition
# This should make things a lot simpler. module Math remove_const(:PI) PI = 3 end Math::PI # => 3