Skip to content

Instantly share code, notes, and snippets.

@palkan
Forked from kddnewton/count_const_refs.rb
Last active January 21, 2022 17:31
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 palkan/0c95f3a685b6a69311859fedb7e1d3cc to your computer and use it in GitHub Desktop.
Save palkan/0c95f3a685b6a69311859fedb7e1d3cc to your computer and use it in GitHub Desktop.
class Array
def deconstruct
self
end
end
class Hash
def deconstruct_keys(_)
self
end
end
class Struct
alias deconstruct to_a
def deconstruct_keys(keys)
raise TypeError, "wrong argument type #{keys.class} (expected Array or nil)" if keys && !keys.is_a?(Array)
return to_h unless keys
keys.each_with_object({}) do |k, acc|
# if k is Symbol and not a member of a Struct return {}
return {} if (Symbol === k || String === k) && !members.include?(k.to_sym)
# if k is Integer check that index is not ouf of bounds
return {} if Integer === k && k > size - 1
acc[k] = self[k]
end
end
end
def count_constant_refs(iseq)
cached = false
iseq.last.each_with_object([]) do |insn, counts|
case; when ((__m__ = insn)) && false
when (__p_1__ = __m__.respond_to?(:deconstruct) && (((__m_arr__ = __m__.deconstruct) || true) && (Array === __m_arr__ || Kernel.raise(TypeError, "#deconstruct must return Array"))) and ((:opt_getinlinecache === __m_arr__[0]) && __m_arr__[1..-1]))
cached = true
counts << 0
when (__p_1__ && ((:getconstant === __m_arr__[0]) && __m_arr__[1..-1]))
counts[counts.length - 1] += 1 if cached
when (__p_1__ && ((:opt_setinlinecache === __m_arr__[0]) && __m_arr__[1..-1]))
cached = false
when (__p_1__ && (((child,) = nil) || __m_arr__.find.with_index { |__el__, __i__| (((Array === __el__) && (("YARVInstructionSequence/SimpleDataFormat" === __el__[0]) && __m_arr__[1..-1])) && ((child = __m_arr__[__i__]) || true)) }))
counts.concat(count_constant_refs(child))
else
end
end
end
[].tap do |counts|
Dir["**/*.rb"].each do |filepath|
iseq = RubyVM::InstructionSequence.compile_file(filepath).to_a
counts << count_constant_refs(iseq)
rescue SyntaxError
end
n, d = counts.sum(&:length), counts.length
puts "Average const refs per file: #{n}/#{d} = #{(n.to_f / d).round(2)}"
n, d = counts.sum(&:sum), n
puts "Average const ref depth: #{n}/#{d} = #{(n.to_f / d).round(2)}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment