Ruby classes: Difference between revisions

From wikinotes
 
(2 intermediate revisions by the same user not shown)
Line 48: Line 48:
</source>
</source>


You can also temporarily replace a method
<source lang="ruby">
<source lang="ruby">
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'
</source>
</source>
For localized monkeypatching, check out [[ruby refinements]].


= Inheritance =
= Inheritance =
Line 129: Line 144:
See http://www.metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/ <br>
See http://www.metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/ <br>
Or https://github.com/shuber/abstract_class
Or https://github.com/shuber/abstract_class
= Dynamic Classes =
You can dynamically generate classes if you must.
<source lang="ruby">
Class.new(SomeSuperClass) do
  def foo
    puts 'hi'
  end
end
</source>

Latest revision as of 16:38, 20 June 2023

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

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