|
#!/usr/bin/env ruby
|
|
#
|
|
# Tested in ruby 2.5.3 and 2.6.3 installed via rbenv.
|
|
#
|
|
|
|
class Name < String
|
|
# Name#to_hash gets called. But why?
|
|
def to_hash
|
|
puts 'Name#to_hash was called.'
|
|
end
|
|
end
|
|
|
|
class Person
|
|
attr_accessor :name
|
|
|
|
def initialize(name = 'world')
|
|
@name = name
|
|
end
|
|
|
|
# The key thing here is the method signature which must contain a default
|
|
# positional parameter followed by a default keyword parameter for the
|
|
# Name#to_hash method to be called. When calling Person#greet only the name
|
|
# parameter should be provided. See my example usage below.
|
|
def greet(name = @name, age: nil)
|
|
if age
|
|
puts "Hello #{name}, you are #{age}"
|
|
else
|
|
puts "Hello #{name}"
|
|
end
|
|
end
|
|
end
|
|
|
|
# [12] pry(main)> n = Name.new 'Michael'
|
|
# => "Michael"
|
|
# [13] pry(main)> p = Person.new
|
|
# => #<Person:0x00007ff0eab4d768 @name="world">
|
|
# [14] pry(main)> p.greet
|
|
# Hello world
|
|
# => nil
|
|
# [15] pry(main)> p.greet n
|
|
# Name#to_hash was called.
|
|
# Hello Michael
|
|
# => nil
|
|
# [16] pry(main)> p.greet n, age: 30
|
|
# Hello Michael, you are 30
|
|
# => nil
|
|
|
|
# Notice how `p.greet n` results in `Name#to_hash` being called. Why?
|
|
# This feels like a bug. I have a defined to_hash method in my code which is
|
|
# being called when I don't want it to be. It should also be noted that if Name
|
|
# didn't respond to :to_hash the code wouldn't complain about the missing
|
|
# method so something like the following must be happening:
|
|
# `obj.to_hash if obj.respond_to? :to_hash`.
|