Reputation: 7866
I have the following two methods that are very similar:
def space_before_element?(start_element)
element = start_element.previous_element
until element.nil? ||
(element.name == start_element.name || "r" && !element.text.empty?)
element = element.previous_element
end
character = element
.text
.split(/(\W)/)
.compact
.reject(&:empty?)
.last
.last_character \
unless element.nil?
element.nil? ||
(character.punctuation? && !character.hyphen? && !character.apostrophe?) ||
character.spaces?
end
def space_after_element?(start_element)
element = start_element.next_element
until element.nil? ||
(element.name == start_element.name || "r" && !element.text.empty?)
element = element.next_element
end
character = element
.text
.split(/(\W)/)
.compact
.reject(&:empty?)
.last
.first_character \
unless element.nil?
element.nil? ||
(character.punctuation? && !character.hyphen? && !character.apostrophe?) ||
character.spaces?
end
I can't seem to figure out how to make the necessary changes that would allow me to reduce this down to one method.
Still getting my Ruby skills going.
Any help appreciated. Ruby 2.2.3
Upvotes: 0
Views: 127
Reputation: 121000
I counted three differences. So, these differences should be explicitly declared:
METHODS = {
prev: [:previous_element, %i|last last_character|],
next: [:next_element, %i|first first_character|]
}.freeze
Now we just pass a parameter to the method:
def space_around_element?(start_element, prev_or_next = :prev)
element = start_element.public_send(METHODS[prev_or_next].first)
# same code
character = element
.text
.split(/(\W)/)
.reject(&:empty?)
.public_send(METHODS[prev_or_next].last.first)
.public_send(METHODS[prev_or_next].last.last) \
unless element.nil?
# same code
end
Upvotes: 4