Skip to content

Instantly share code, notes, and snippets.

@MaxLap
Last active May 20, 2024 12:39
Show Gist options
  • Save MaxLap/0e133bf6f27f2437193dc034d58083dc to your computer and use it in GitHub Desktop.
Save MaxLap/0e133bf6f27f2437193dc034d58083dc to your computer and use it in GitHub Desktop.
Using RubyNext to show negated method calls, such as `foo.!exists?`
class NegatedMethodRewriter < Parser::TreeRewriter
def on_send(node)
receiver_node, method_name, *arg_nodes = *node
if receiver_node && method_name == :! && arg_nodes.size == 1
remove(node.location.selector)
insert_before(node.location.expression, "!(")
insert_after(node.location.expression, ")")
else
super
end
end
end
RubyNext.define_text_rewriter "negated_calls" do
def safe_rewrite(source)
buffer = Parser::Source::Buffer.new('(example)', source: source)
ast = Parser::CurrentRuby.parse(source)
NegatedMethodRewriter.new.rewrite(buffer, ast).dup
end
end
class A def foo
true
end
def exists?(...)
false
end
def long_method_name(...)
self
end
end
# Compare the following equivalent triples that negate a method
puts !(A.new.foo)
puts A.new.foo.!
puts A.new.!foo # New!
puts !(A.new.exists?(with_friends: true, skip_administrator: true))
puts A.new.exists?(with_friends: true, skip_administrator: true).!
puts A.new.!exists?(with_friends: true, skip_administrator: true) # New!
my_a_to_show = A.new
puts !(my_a_to_show.long_method_name(something: :here).exists?)
puts my_a_to_show.long_method_name(something: :here).exists?.!
puts my_a_to_show.long_method_name(something: :here).!exists? # New!
# To me, the .!exists? is much better than the other options
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment