I've been doing some 'monkey-patching' (ahem excuse me superman-patching), like so, adding the below code and more to file(s) in my "#{Rails.root}/initializers/"
folder:
module RGeo
module Geographic
class ProjectedPointImpl
def to_s
coords = self.as_text.split("(").last.split(")").first.split(" ")
"#{coords.last}, #{coords.first}"
end# of to_s
def google_link
url = "https://maps.google.com/maps?hl=en&q=#{self.to_s}"
end
end# of ProjectedPointImpl class
end# of Geographic module
end
I ended up realizing that there were two different _Point_
instances which I wanted to utilize these methods on (both were strings with the same formatting, i.e. Well-Known Text (WKT)), and added an exact copy of the above two methods to a certain RGeo::Geos::CAPIPointImpl
class space.
I then, in my youthful, unexperienced way, after thinking about DRY (don't repeat yourself) principles, proceeded to create an ad hoc class which I presumed I might be able to inherit from for both
class Arghhh
def to_s
coords = self.as_text.split("(").last.split(")").first.split(" ")
"#{coords.last}, #{coords.first}"
end# of to_s
def google_link
url = "https://maps.google.com/maps?hl=en&q=#{self.to_s}"
end
end
and told my classes to inherit from it i.e.: ProjectedPointImpl < Arghhh
I was promptly responded to by ruby with this error when I stopped and then tried to reload my rails console:
`<module:Geos>': superclass mismatch for class CAPIPointImpl (TypeError)
...
I think my naivete in trying to get CAPIPointImpl (in this case) to inherit from another class than its parent also highlights my knowledge gap on this subject very explicitly
What methods might I be able to use to practically graft extra shared methods onto two classes coming from otherwise separate parents? Does ruby allow for these types of abstract exceptions?
What you need to do is to define the new methods in a module which you then "mix into" the existing classes. Here's a rough sketch:
# Existing definition of X
class X
def test
puts 'X.test'
end
end
# Existing definition of Y
class Y
def test
puts 'Y.test'
end
end
module Mixin
def foo
puts "#{self.class.name}.foo"
end
def bar
puts "#{self.class.name}.bar"
end
end
# Reopen X and include Mixin module
class X
include Mixin
end
# Reopen Y and include Mixin module
class Y
include Mixin
end
x = X.new
x.test # => 'X.test'
x.foo # => 'X.foo'
x.bar # => 'X.bar'
y = Y.new
y.test # => 'Y.test'
y.foo # => 'Y.foo'
y.bar # => 'Y.bar'
In this example we have two existing classes X
and Y
. We define the methods we would like to add to both X
and Y
in a module which I've called Mixin
. We can then reopen both X
and Y
and include the module Mixin
into them. Once that's done, both X
and Y
have their original methods plus the methods from Mixin
.