Reputation: 15089
Let's say I have the following structure inside my Ruby project (actually, Ruby On Rails 5, but I guess this is more about Ruby than RoR5):
main.rb
greeter.rb
impl/dog.rb
impl/cat.rb
config.yaml
How would I implement an interface in 'greeter.rb' in such a way so I could get to see a 'bau bau!' in the output if I run the following (pseudo)code:
//main.rb
include greeter.rb
greet()
//config.yaml
greeter = Dog
//dog.rb
def greet()
print 'bau bau!'
end
//cat.rb
def greet()
print 'miau!'
end
Upvotes: 0
Views: 1338
Reputation: 211670
While this might be the way you're thinking about solving the problem, from the perspective of Ruby it's totally wrong. What you want is something like this:
# lib/animal.rb
class Animal
def self.of_type(type, *args)
case (type)
when 'cat'
Cat.new(*args)
when 'dog'
Dog.new(*args)
end
end
end
# Explicitly load subclasses
require_relative('./cat')
require_relative('./dog')
Now that loads in two specific sub-classes that implement the specific behaviours:
# lib/cat.rb
class Cat < Animal
def greet
"Mew!"
end
end
# lib/dog.rb
class Dog < Animal
def greet
"Woof!"
end
end
You can write a simple test script to verify this, but using test/unit
, rspec
or Minitest is even better:
# test/example.rb
require_relative('../lib/animal')
Animal.of_type('dog').greet
# => "Woof!"
Note that in Ruby methods with no arguments have their brackets removed, they're not required and tradition holds they be omitted for simplicity. Likewise, lib/
is where most library "implementations" are stored.
There's generally no main.rb
file as there's generally no main
method. You just set up things in either a bin/
type script, or as part of something else, like your test framework or web environment.
Upvotes: 1