Ruby classes
Basics
class MyClass
# constructor
def initialize()
@instance_var = "b"
end
end
if __FILE__ == $0
myclass = MyClass.new('my classname')
end
Classes, Singleton Classes and Instances
TODO:
- see (singleton_class) https://medium.com/@leo_hetsch/demystifying-singleton-classes-in-ruby-caf3fa4c9d91
- see (class instance-variables) https://www.codegram.com/blog/understanding-class-instance-variables-in-ruby/
MonkeyPatching
The same class defined multiple times is not a name-clash
In ruby, this results in a globally monkey-patched object.
In the example below, the final result is a single ::Foo::Bar
with both methods print_hello
and print_bye
.
# file_a.rb
module Foo
class Bar
def print_hello
puts 'hello'
end
end
end
# file_b.rb
module Foo
class Bar
def print_bye
puts 'bye'
end
end
end
You can also temporarily replace a method
class Foo
def bar = "orig-bar"
end
Foo.new.bar # 'orig-bar'
# change 'bar()'
orig_bar = Foo.instance_method(:bar)
Foo.define_method(:bar) { "new-bar" }
Foo.new.bar # 'new-bar'
# restore original 'bar()'
Foo.define_method(:bar, orig_bar)
Foo.new.bar # 'orig-bar'
For localized monkeypatching, check out ruby refinements.
Inheritance
- multiple inheritance is impossible in ruby
class MySubclass < MyClass
end
Include
include functions defined in a module into your class's instance methods.
- multiple modules can be included in a single class (unlike inheritance).
- functions bound as instance methods, that call functions on the module's instance
- changing the included module will change the instance for other classes that include it
module MyModule
def speak
p 'hello'
end
end
class MyClass
include MyModule
end
myclass = MyClass.new
myclass.speak
#>>> 'hello'
Extend
include methods defined in a module into your class's class methods.
module MyModule
def speak
p 'hello'
end
end
class MyClass
extend MyModule
end
MyClass.speak
#>>> 'hello'
method_missing
If a method is not defined on the object, you can respond to it your own way.
class Foo
def initialize
@wrapped = FooBar.new
end
def bar
"bar"
end
def method_missing(symbol, *args)
@wrapped.send(symbol, *args)
end
end
type checks
instance.is_a?(MyClass) # test is instance of
if ClassA < ClassB # test is subclass
Interfaces
Ruby does not implement interfaces, but you can write your own implementation.
See http://www.metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/
Or https://github.com/shuber/abstract_class
Dynamic Classes
You can dynamically generate classes if you must.
Class.new(SomeSuperClass) do
def foo
puts 'hi'
end
end