I am trying to create a global boolean method that checks if a variable is of type Pair
(my own customized class). However, when I try to run it, I get the error
Project4.rb:83:in `<main>': private method `pair?' called for #<Pair:0x00000212de6861e8 @value1=5, @value2=7> (NoMethodError)
puts a.pair?
^^^^^^
What do I do? My code is below.
#Pair (class): Takes two values and creates a list from them. Executing the code should return a list without displaying any output.
# Returns: A list of at least two elements.
# Parameters:
# value1 (any class, including pair) - a value to insert into list.
# value2 (any class, including pair) - another value to insert into list.
#
#Declare class `Pair`
class Pair
#Initialize
def initialize(value1, value2)
@value1 = value1
@value2 = value2
end
#Method: car - return the car of the pair.
def car
return @value1
end
#Method: cdr - return the cdr of the pair.
def cdr
return @value2
end
#Method: to_s - Return string representation of the pair.
# def to_s
# "(#{@value1} . #{@value2})"
# end
#Method: list? - returns true if pair is a valid list and false otherwise.
def list?
#If value2 is a pair...
if (@value2.class == Pair)
#...Recursively call the list? method again with the cdr.
cdr.list? #Recursion
else
#If value2 is a null (nil) value, then it is a list.
if (@value2 == nil)
return true
else
return false
end
end
end
#Method: count - If the pair is a list, return the number of items in the top level of the list. Return false otherwise.
#Method: append(other) - If the pair is a list, append should return a new list consisting of `other`` appended to the original list.
#Method: null? - returns true only if the pair is an empty list.
def null?
end
#Implement a null/empty list value.
def self.null
nil
end
end
#Implement a global `pair?` method. MUST NOT TAKE PARAMETERS!
def pair?
if (is_a? Pair)
return true
else
return false
end
end
Please reply at your earliest conveniene.
A global method doesn't require a receiver and can be called in functional form, for example puts
or loop
. Your method however does require a receiver because it's based on is_a?
.
To turn your method into a working global method, you'd need to pass the object:
def pair?(obj)
obj.is_a?(Pair)
end
MUST NOT TAKE PARAMETERS!
Okay, noted. You probably don't want a global method in the first place but an instance method of Object
:
class Object
def pair?
is_a?(Pair)
end
end
This is "global" in the sense that you can call it on any object.
You can even omit the explicit type check by utilizing inheritance. Implement a Object#pair?
method which provides a default value of false
for all objects:
class Object
def pair?
false
end
end
and override it in your Pair
class to return true
:
class Pair
def pair?
true
end
end
Example:
Object.new.pair? #=> false
"a string".pair? #=> false
Pair.new.pair? #=> true
This is exactly how nil?
works, see the implementation for Object#nil?
and NilClass#nil?
.
Keep in mind that adding methods to Object
might result in cluttered classes as those methods become available to all objects. It's great for exploring OOP principles but you shouldn't do it in general.