How to check all classes under or using a class? [duplicate] - ruby

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Look up all descendants of a class in Ruby
So, let's say that we have:
class LivingBeing
class Animal
end
class Bacteria
end
class Virus
end
end
class Fungi < LivingBeing
end
How do I check what subclasses LivingBeing has? I know that we have Klass.ancestors but what's the method to see the opposite of ancestors?

There's nothing built into the core Ruby language that will do what you want - you'll need to write your own. Here's an example method subclasses_of(class_name_here) (below) that will return a list of subclasses of a particular class for you:
class Mammal
end
class Human < Mammal
end
class Dog < Mammal
end
def subclasses_of input
ObjectSpace.each_object(Class).select { |klass| klass < input }
end
subclasses_of(Mammal)
#=> [Human, Dog]
Btw, there's an answer to this question here:
http://dzone.com/snippets/objectsubclasses

Related

How to avoid abstract class pattern in Ruby? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Abstract class looks in Ruby code like an alien from remote planet Java. I'm trying to collect Ruby tricks which can substitute this unwanted pattern.
Let's take a completely random example:
class AbstractRace < Struct.new(:runner_count)
def go!
runner_count.times.map do |index|
Thread.new do
run(index)
end
end.each(&:join)
end
def run(index)
raise 'To be implemented in derivative classes'
end
end
class RunnerRace < AbstractRace
def run(index)
puts "I am runner number #{index}. I am running"
end
end
class CarRace < AbstractRace
def run(index)
puts "I am car number #{index}. I am accelerating"
end
end
RunnerRace.new(2).go!
CarRace.new(2).go!
How to rewrite it? A possible approach would be using a mixin, like this:
require 'active_support/concern'
module Race
extend ActiveSupport::Concern
def go!
participant_count.times.map do |index|
Thread.new do
run(index)
end
end.each(&:join)
end
module ClassMethods
def configure_race(methods)
[:participant_count, :run].each do |method_symbol|
define_method method_symbol, methods[method_symbol]
end
end
end
end
class RunnerRace < Struct.new(:runner_count)
include Race
configure_race participant_count: ->() { runner_count },
run: ->(index) { puts "I am runner number #{index}. I am running" }
end
class CarRace < Struct.new(:car_count)
include Race
configure_race participant_count: -> { car_count },
run: ->(index) { puts "I am car number #{index}. I am going" }
end
RunnerRace.new(2).go!
CarRace.new(2).go!
What other solutions could be? Is there a common idiom for such case?
Why not just take advantage of the fact that Ruby is a dynamic language?
class Race
attr_reader :participants
def initialize(participants)
#participants = participants
end
def go!
participants.each_with_index.map do |index,participant|
Thread.new do
participant.run(index)
end
end.each(&:join)
end
end
class CarEntry
def run(index)
puts "I am car number #{index}. I am going"
end
end
There is no need for anything running in a 'race' to extend a superclass. All anything in the race must do is be capable of racing i.e having a
run(index)
method that does something.
In ruby I would tend to think of 'AbstractRace' as more of a role for a class to play. Roles are best encapsulated in modules (as you've suggested in your first response).
If you are trying to come up with a general ruby solution, however, I would recommend removing the reference to ActiveSupport::Concern. This module is something that comes from Rails and may not be available in all ruby environments.
There is nothing wrong with what you have written there and I'm not entirely sure what you are unhappy with.
That being said, this is Ruby and there is no need to define the run method on your AbstractRace class. If that's what is bothering you, then just don't do it.
The reason you put it there is to show both yourself and other developers who might be working on the code that a Race should have a run method. It's defining the interface. It definitely is not required though, but it is the "proper" way to make an object oriented class hierarchy.
I think you're missing the point of abstract classes
Languages like Java use abstract classes because they want to:
Collect common code for derived classes in one place (common base class), and
Prevent instantiating this common base class, because it is a base class.
If you wanted to achieve the same goals, you could do this by:
Creating a base class with the common code
Giving it a private constructor:
```
class AbstractRace
private:
def initialize
end
end
```
The other reason people use abstract classes, is the same as interfaces: they want to guarantee that some method exists on a derived class.
Unfortunately, there's no such construction as Ruby; in fact, this is "un-Ruby-like." In Ruby, we rely on "duck typing," which means "if it quacks, it's a duck!" Observe:
class Car
def drive
return 'VROOOM!'
end
end
class Duck
def quack
return 'Quack quack!'
end
end
test_objs = [Car.new, Duck.new]
test_objects.each do |some_obj|
if some_obj.respond_to?(:quack)
puts "#{some_obj} is a duck! #{some_obj.quack}"
else
puts 'Not a duck, sorry.
end
end
This will output something like <Duck:0x123456> is a duck! Quack quack!
This is relying on "duck typing," by checking for the existence of methods before using them. This is the closest idiom in Ruby.

ruby difference between class ClassName and class ::ClassName [duplicate]

This question already has answers here:
What is Ruby's double-colon `::`?
(12 answers)
Closed 8 years ago.
what's the difference between class ClassName and class ::ClassName in ruby?
class ClassName
end
vs
class ::ClassName
end
Your two examples would make difference if the classes were defined inside a ruby module, so:
module Foo
class ClassName
end
end
would define a new class inside the Foo module. This could be accessed like Foo::ClassName.
On the other hand, this:
module Foo
class ::ClassName
end
end
would define (or monkey-patch) the class ClassName in the root namespace.
::Class says 'look for Class in top level namespace'. The difference shows when in context of a module.
module A
def foo
X.new
end
end
A.foo # => A::X.new
module B
def foo
::X.new
end
end
B.foo # => X.new

What's the purpose of the 'attr_accessor' in creating objects in Ruby? [duplicate]

This question already has answers here:
What is attr_accessor in Ruby?
(20 answers)
Closed 8 years ago.
Before I expand my question, let me state that I have read the answers to the questions here, here and here. So requesting you to not mark my question as duplicate as those answers didn't make me understand the purpose of attr_accessor. My question is more to do with the logic and not the syntax.
I've created two sets of code below. The sets are identical to each other except that one set simply doesn't have the attr_accessor line. When I ran both sets, they both gave me the same output. So, logically speaking, what difference does the attr_accessor line make, when both sets of code gave me the same intended output?
Code Set 1:
class Animal
def initialize(name)
#name = name
end
end
class Cat < Animal
def talk
"Meaow!"
end
end
class Dog < Animal
def talk
"Woof!"
end
end
animals = [Cat.new("Flossie"), Dog.new("Clive"), Cat.new("Max")]
animals.each do |animal|
puts animal.talk
end
#Output:
#Meaow!
#Woof!
#Meaow!
Code Set 2:
class Animal
attr_accessor :name #this line is the only difference between the two code sets.
def initialize(name)
#name = name
end
end
class Cat < Animal
def talk
"Meaow!"
end
end
class Dog < Animal
def talk
"Woof!"
end
end
animals = [Cat.new("Flossie"), Dog.new("Clive"), Cat.new("Max")]
animals.each do |animal|
puts animal.talk
end
#Output:
#Meaow!
#Woof!
#Meaow!
Both sets of code call the Animal class to create new instances of animal objects WITH names. I stress on "...WITH names." because the attr_accessor (in the 2nd set) is defining the :name attribute. But in the 1st code set, I have deleted the attr_accessor but still managed to create object instances with the name attribute.
attr_accessor :attribute_name is shorthand for:
def attribute_name
#attribute_name
end
def attribute_name=(value)
#attribute_name = value
end
and it's for setting instance variable. In your code snipped, you set instance variable directly in initialize method, so you don't need attr_accessor.
Instance variables can always be read/written inside instance methods, which your code demonstrates. attr_accessor makes instance variables readable/writable outside the class (by defining accessor methods). By adding it to your second example, you allow the following:
cat = Cat.new("Garfield")
puts cat.name
cat.name = "Maru"
which would raise NoMethodError in your first example.

What is this line of Ruby code doing? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
class << self idiom in Ruby
I was wondering what this code is doing. I don't understated this one line. I know what attr_accessor is.
class User
class << self; attr_accessor :base_uri end
....
....
...
You will see class << self used often in Ruby. The easiest way to understand what it does is to think of it as (almost) equivalent to this:
class Abc
self.attr_accessor ...
end
Which is basically the same as this:
Abc.class.attr_accessor ...
But you really can't do either of those because:
> Abc.class.attr_accessor :blah
NoMethodError: private method `attr_accessor' called for Class:Class
So to get around it you'd have to do:
> Abc.class.send(:attr_accessor, :blah)
Or:
class Abc
self.send(:attr_accessor, :blah)
end
That's where the << self construct comes in since it gives you access to these private methods. You are basically operating directly in "self-space".
Similarly when you see:
class Abc
class << self
def foo
end
end
end
It's just the same as saying:
class Abc
def self.foo
end
end
Which will define a class method, just like the code in your question will define a class-level attr_accessor.
EDIT
As for a less complicated way - Ruby doesn't really by default have a method that is able to create class-level attr_accessors. That's why you have to use the << self trick.
But Rails does define a method that does something similar without having to use << self. In Rails you have cattr_accessor:
class Abc
cattr_accessor :blah
end
Abc.blah = 123
Abc.blah
>> 123
This let define an instance variable in the class context.
See the code:
class User
class << self; attr_accessor :base_uri end
#base_uri = "aaa";
end
p User.base_uri # will output "aaa"

What is the class << self in ruby [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why isn't the eigenclass equivalent to self.class, when it looks so similar?
class << self idiom in Ruby
I have this class:
class Player < ActiveRecord::Base
before_save :set_slug
def remains
((end_date - Date.today) + 1).to_i
end
def self.url
"Our_link_#{slug}"
end
class << self
def load_track_lists
#do somthing
end
end
end
and I understand the class and instance methods but the
class << self
def load_track_lists
#do somthing
end
end
is really confusing. What is it and how does it differ from the prior two methods?
The end result is basically the same as if it had been defined as
def self.load_track_lists
#do somthing
end
There are subtle differences between the two methods if you're doing more than just defining methods in the class << self block, as described in the linked question, but effectively you're "opening up" the current class to define class level methods in it.
It doesn't differ from the self.url method. It's basically a container that allows you to put multiple methods without having to put self. in front of the method name. Probably not useful in the example but can be quite clean for other classes.
IMO it's a developer's preference

Resources