Skip to content

Instantly share code, notes, and snippets.

@baweaver
Created December 31, 2018 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baweaver/807d2624ec2a393fd7356d76937359dc to your computer and use it in GitHub Desktop.
Save baweaver/807d2624ec2a393fd7356d76937359dc to your computer and use it in GitHub Desktop.
First round of argument ripper
# Based on: https://twitter.com/josh_cheek/status/1079827841095749632
require 'method_source'
require 'parser/ruby25'
module ArgRipper
class << self
def get_args(meth)
Parser::Ruby25
.parse(meth.source)
.then(&method(:extract_args))
.children
.select { |arg| arg.type == :kwoptarg }
.map(&method(:expression_source))
.to_h
end
private def extract_args(ast)
return nil unless ast.is_a?(Parser::AST::Node)
return ast if ast.type == :args
ast.children.find { |child| extract_args(child) }
end
private def expression_source(argument)
name, value = argument.children
[name, value.location.expression.source]
end
end
end
def part1(before:, after:, instruction: [_op, a, b, c])
[1, 2, 3].map &transform||:to_s
end
def part2(instruction: { a: { b: { c: 2 }}}) end
def part3(instruction: OpenStruct.new(a: { b: { c: 2 }})) end
p ArgRipper.get_args(method(:part1))
# => {:instruction=>"[_op, a, b, c]"}
p ArgRipper.get_args(method(:part2))
# => {:instruction=>"{ a: { b: { c: 2 }}}"}
p ArgRipper.get_args(method(:part3))
# => {:instruction=>"OpenStruct.new(a: { b: { c: 2 }})"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment