Skip to content

Instantly share code, notes, and snippets.

@profh
Created March 15, 2022 13:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save profh/33eb3cb702d1983d26b6fcd958a379f1 to your computer and use it in GitHub Desktop.
Save profh/33eb3cb702d1983d26b6fcd958a379f1 to your computer and use it in GitHub Desktop.
A quick intro to Ruby object model
# Examples: looking at classes and ancestors
5.class # => Integer
5.class.ancestors # => [Integer, Numeric, Comparable, Object, Kernel, BasicObject]
"Quack".class # => String
"Quack".class.ancestors # => [String, Comparable, Object, Kernel, BasicObject]
[1,2,3].class # => Array
[1,2,3].class.ancestors # => [Array, Enumerable, Object, Kernel, BasicObject]
d = class Duck; self; end; # making a quick class
daffy = Duck.new # making an instance of that class
d.class # => Class
d.class.ancestors # => [Class, Module, Object, Kernel, BasicObject]
daffy.class # => Duck
daffy.class.ancestors # => [Duck, Object, Kernel, BasicObject]
# Note that everything -- integers, arrays, strings, classes -- are part of Object
5.kind_of? Object # => true
"Quack".kind_of? Object # => true
[1,2,3].kind_of? Object # => true
d.is_a? Object # => true
daffy.is_a? Object # => true
# --------------------
daffy.instance_of? Duck # => true
daffy.instance_of? Object # => false
# Object receive messages
"quack".send :upcase # => "QUACK"
5.send :+, 9 # => 14
[1,2,3].send :nil? # => false
d.send :class # => Class
daffy.send :class # => Duck
# Object responds to messages
"quack".respond_to? :length # => true
5.respond_to? :+ # => true
###############################################
##### Example of the pen and the scribe #####
###############################################
# create a pen object
pen = Object.new # => #<Object:0x007f8f3c0ca378>
# add a method to the pen
def pen.to_s # !> previous definition of to_s existed and we are overwriting it
"A trusty pen"
end
# see that this method works as expected
pen.send :to_s # => "A trusty pen"
pen.to_s # => "A trusty pen"
pen # => A trusty pen (the to_s method served as the object's name now)
# let's start writing with our pen...
# pen.write "nunqeh Terran"
## => NoMethodError: undefined method `write' for A trusty pen:Object
# fine, then let's add a method to this pen object so it can write
def pen.write(words)
puts words
end
pen.write "nunqeh Terran"
# => nil >> nunqeh Terran
pen.write pen
# => nil >> A trusty pen
# let's make the pen a blue ink pen (b/c blue is an awesome color...)
# pen.ink_color = "Blue"
## => NoMethodError: undefined method `ink_color' for A trusty pen:Object
# okay, let's define the method ink_color for the pen object
def pen.ink_color=(color)
@ink_color = color
end
# now set the color to blue
pen.ink_color = "Blue" # => "Blue"
# let's update to_s to add in the color
def pen.to_s # !> method redefined; discarding old to_s
"A trusty #{@ink_color.downcase} pen"
end
# verify that it works
p pen.send :to_s # => "A trusty blue pen"
# writing a method that adds 'sparkles' to words to demo implicit receivers
def pen.sparkly_write words
write "*;. #{words} *;.*" # note the implicit receiver
end
pen.sparkly_write "Sparkles! (sort of)"
## => nil >> *;. Sparkles! (sort of) *;.*
pen.sparkly_write pen
## => nil >> *;. A trusty blue pen *;.*
# create a method to write html
def pen.html_write words
if @ink_color
write "<p style=\"color: #{@ink_color.downcase};\">#{words}</p>"
# sorry for adding the color style right in the p tag but works for a demo...
else
write "<p>#{words}</p>"
end
end
# now try this method out...
pen.html_write "Sorry Lizzie for the embedded style"
# => nil >> <p style="color: Blue;">Sorry Lizzie for the embedded style</p>
# time for a break in the action
puts Array.new(20, "-").join
puts
# create a scribe class who will actually use the pen object we created
class Scribe
def initialize pen
# a scribe needs almost by definition a pen, quill, etc.
@pen = pen
# a list of items we want the scribe to record
@list = Array.new
end
# Getters and setters manually...
# def list
# @list
# end
#
# def pen
# @pen
# end
#
# def pen=(pen)
# @pen = pen
# end
#
# the easy way in Ruby... (same results as above)
attr_reader :list
attr_accessor :pen
def note item
# when we tell the scribe to make a note, he/she adds it to the list
@list << item
end
def write_everything
# when we want to see all the items in the list
@list.each{ |item| @pen.html_write item }
end
end
# one of the most famous scribes in the O.T. was Ezra
# (and the only one I can think of right now), so ...
ezra = Scribe.new pen
# let's verify that Ezra has the pen object we've created
p ezra.pen
# time for Ezra to make some notes; first will be the time itself
ezra.note "The time is #{Time.now}"
# verify that the note is on the list
p ezra.list
# one more note for good measure
ezra.note "Time to read the Law to the people"
# now print it all out with the pen
ezra.write_everything
## OUTPUT:
# >> The time is 2018-03-06 12:37:03 -0400
# >> Time to read the Law to the people
# time for another break in the action
puts Array.new(20, "-").join
puts
# follow-up on previous ideas...
# adding a method to just the ezra object
def ezra.speak_hebrew
puts "Hallelujah"
end
ezra.speak_hebrew
# creating a new scribe
hammurabi = Scribe.new(pen)
puts hammurabi.pen
hammurabi.respond_to? :note # => true
hammurabi.respond_to? :speak_hebrew # => false
# since Babylonians don't speak hebrew ...
# hammurabi.speak_hebrew # ... will fail
# creating a clone of an object
pen2 = pen.clone
pen2.write("Matt")
puts pen.object_id
puts pen2.object_id # different object id
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment