Skip to content

Commit

Permalink
adhoc exercises
Browse files Browse the repository at this point in the history
  • Loading branch information
skmetz committed Oct 28, 2015
1 parent 830640d commit 7cf0971
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 0 deletions.
65 changes: 65 additions & 0 deletions adhoc/objects_and_messages.rb
@@ -0,0 +1,65 @@
###############################
# a bit of simple math
###############################
1 + 2 # => 3

# what is it?
1.class # +> Fixnum

# what does it know?
Fixnum.instance_methods
Fixnum.instance_methods.class # => Array
Fixnum.instance_methods.sort
Fixnum.instance_methods.size

Fixnum.superclass
Fixnum.ancestors
Fixnum.instance_methods(false).size
Fixnum.instance_methods(false).sort
Fixnum.instance_methods(false).sort[4] # +> :+
Fixnum.instance_methods(false).sort[4].class # +> Symbol
# http://ruby-doc.org/core-2.0.0/Symbol.html



###############################
# 1 + 2 is syntactic sugar
###############################
1 + 2 # => 3
1 +(2) # => 3, parens are optional
1.+(2) # => 3, the '.' was inferred

1.send(:+, 2) # => 3, the symbol represents a message

message = '+'
1.send(message.to_sym, 2) # => 3, sending a dynamically constructed message

1.public_send(:+, 2) # => 3, only sending if it's public



###############################
# a simple equality comparison
###############################
1 == 2

# what is it?
(1 == 2).class

# what does it know?
FalseClass.instance_methods
FalseClass.instance_methods.sort
FalseClass.instance_methods.size

FalseClass.superclass
FalseClass.instance_methods(false).size
FalseClass.instance_methods(false).sort

# Look at the source for FalseClass #&
# http://ruby-doc.org/core-2.0.0/FalseClass.html

nil.class
# Look at the source for NilClass #&
# http://ruby-doc.org/core-2.0.0/NilClass.html

# Fixnums, Symbols, true, false, and nil are 'immediate' objects.
94 changes: 94 additions & 0 deletions adhoc/ruby_hierarchy.rb
@@ -0,0 +1,94 @@
####################
# Exploring the Ruby Object Hierarchy
####################
1.class # => Fixnum
Fixnum.superclass
Fixnum.ancestors

# what is the class of any class?
Fixnum.class # => Class
Integer.class # => Class


# what are the classes of all of my ancestors?
Fixnum.ancestors.collect {|ancestor| "(#{ancestor.class}) #{ancestor}"}

# what is this module thing?
Module.class # => Class

Class.superclass # => Module
Module.superclass # => Object
# Therefore: Class is a Module is an Object


# Re-open the Class class and define a new method.
class Class
def subclasses
ObjectSpace.each_object(Class).select { |klass| klass < self }
end
end

# Now I can send #subclasses to any instance of Class
Fixnum.ancestors # look upwards
Fixnum.subclasses # look downwards
Integer.subclasses # "
Numeric.subclasses # "

# The current #subclasses method shows every decendant of a Class,
# i.e. Numeric has subclass Integer, which has subclasses Bignum and Fixnum.
# It shows everthing in the hierarchy below the starting class.

# What if I want to see a nested hierarchy?
class Class

# find immediate subclasses only
def subclasses(parent=self)
ObjectSpace.each_object(Class).select { |klass| klass.superclass == parent }
end

# find decendant subclass
def decendants
ObjectSpace.each_object(Class).select { |klass| klass < self }
end

# recurse down the hiearchy
def nested_subclasses(parent=self)
subclasses(parent).collect {|subclass|
{subclass => nested_subclasses(subclass)}
}
end
end

Fixnum.subclasses # => []

Integer.subclasses # => [Bignum, Fixnum]
Integer.decendants # => [Bignum, Fixnum]

Numeric.subclasses # => [Complex, Rational, Float, Integer]
Numeric.decendants # => [Complex, Rational, Bignum, Float, Fixnum, Integer]
Numeric.nested_subclasses # correct result, but it's ugly

class Class

def nested_subclasses(parent=self)
subclasses(parent).collect {|subclass|
next_level_subclasses = nested_subclasses(subclass)

if next_level_subclasses.empty?
subclass
else
{subclass => next_level_subclasses}
end
}
end

end

Numeric.nested_subclasses # => [Complex, Rational, Float, {Integer=>[Bignum, Fixnum]}]
Exception.nested_subclasses # ...

# Bonus: What happens is you send #subclasses to an instance of Module?
# How would you fix this?
Comparable.class # => Module
Comparable.subclasses
# => NoMethodError: undefined method `subclasses' for Comparable:Module

0 comments on commit 7cf0971

Please sign in to comment.