DEV Community

Lazy coder
Lazy coder

Posted on

irbrc to help with your efficiency

 IRB.conf[:PROMPT][:DEV] = { # name of prompt mode :AUTO_INDENT => false, # disables auto-indent mode :PROMPT_I => ">> ", # simple prompt :PROMPT_S => nil, # prompt for continuated strings :PROMPT_C => nil, # prompt for continuated statement :RETURN => " ==>%s\n" # format to return value } #IRB.conf[:PROMPT_MODE] = :MY_PROMPT # Tracking and Debugging Helpers # Log method calls with their arguments # Usage: track_method_calls(User, :save) def track_method_calls(klass, method_name) klass.class_eval do old_method = instance_method(method_name) define_method(method_name) do |*args, &block| puts "Calling #{klass}##{method_name} with args: #{args.inspect}" old_method.bind(self).call(*args, &block) end end end # Track SQL queries # Usage: track_sql_queries def track_sql_queries ActiveSupport::Notifications.subscribe('sql.active_record') do |*args| event = ActiveSupport::Notifications::Event.new(*args) puts "SQL Query: #{event.payload[:sql]}" puts "Duration: #{event.duration.round(2)} ms" puts "---" end end # Count method calls # Usage: count_method_calls(User, :update) def count_method_calls(klass, method_name) count = 0 klass.class_eval do old_method = instance_method(method_name) define_method(method_name) do |*args, &block| count += 1 puts "#{klass}##{method_name} called #{count} times" old_method.bind(self).call(*args, &block) end end end # Track object allocations # Usage: track_allocations { your_code_here } def track_allocations require 'objspace' GC.disable before = ObjectSpace.count_objects yield after = ObjectSpace.count_objects puts "Object allocations:" after.each do |key, value| diff = value - before[key] puts " #{key}: #{diff}" if diff != 0 end ensure GC.enable end # Profile code execution # Usage: profile_code { your_code_here } def profile_code require 'ruby-prof' RubyProf.start yield result = RubyProf.stop printer = RubyProf::FlatPrinter.new(result) printer.print(STDOUT) end # Track method execution time # Usage: track_time(User, :expensive_method) def track_time(klass, method_name) klass.class_eval do old_method = instance_method(method_name) define_method(method_name) do |*args, &block| start_time = Time.now result = old_method.bind(self).call(*args, &block) end_time = Time.now puts "#{klass}##{method_name} took #{(end_time - start_time) * 1000.0} ms" result end end end # Log instance variable changes # Usage: track_ivar_changes(user, :name) def track_ivar_changes(object, ivar_name) object.define_singleton_method("#{ivar_name}=") do |value| old_value = instance_variable_get("@#{ivar_name}") instance_variable_set("@#{ivar_name}", value) puts "#{object.class}##{ivar_name} changed from #{old_value.inspect} to #{value.inspect}" end end # Memory usage tracker # Usage: track_memory { your_code_here } def track_memory memory_before = `ps -o rss= -p #{Process.pid}`.to_i yield memory_after = `ps -o rss= -p #{Process.pid}`.to_i puts "Memory usage increased by #{memory_after - memory_before} KB" end def compare_methods(count = 1, *methods) require 'benchmark' Benchmark.bmbm do |b| methods.each do |method| b.report(method) { count.times { send(method) } } end end nil end def pp_hash(hash, indent=1) hash.each do |k, v| print " " * indent if v.is_a?(Hash) puts "#{k}:" pp_hash(v, indent+1) else puts "#{k}: #{v}" end end end def measure_allocation before = GC.stat(:total_allocated_objects) yield after = GC.stat(:total_allocated_objects) puts "Allocated objects: #{after - before}" end def http_get(url) require 'httparty' response = HTTParty.get(url) puts "Status: #{response.code}" puts "Body: #{response.body}" end def explore_relation(relation) puts "SQL: #{relation.to_sql}" puts "Explained:" puts relation.explain end def parse_json(json_string) require 'json' JSON.pretty_generate(JSON.parse(json_string)) end def list_constants(mod) mod.constants.sort.each do |const| puts "#{const} = #{mod.const_get(const)}" end end # Usage: class_hierarchy(Array) def class_hierarchy(klass) hierarchy = [klass] while (klass = klass.superclass) hierarchy << klass end hierarchy.each_with_index do |k, i| puts "#{' ' * i}#{k}" end end # Usage: method_info("hello", :upcase) def method_info(obj, method_name) method = obj.method(method_name) puts "Name: #{method.name}" puts "Owner: #{method.owner}" puts "Parameters: #{method.parameters}" puts "Arity: #{method.arity}" puts "Source Location: #{method.source_location&.join(':')}" end # Usage: set_breakpoint(User, :save) def set_breakpoint(klass, method_name) require 'pry' klass.send(:define_method, method_name) do |*args, &block| binding.pry super(*args, &block) end end # Usage: list_instance_variables(some_object) def list_instance_variables(obj) obj.instance_variables.each do |var| puts "#{var}: #{obj.instance_variable_get(var).inspect}" end end # Usage: show_ancestors(Array) def show_ancestors(klass) puts "Ancestors:" klass.ancestors.each { |ancestor| puts " #{ancestor}" } puts "\nIncluded Modules:" (klass.ancestors - klass.superclass.ancestors - [klass]).each { |mod| puts " #{mod}" } end # Usage: list_constants def list_constants Module.constants.sort.each do |constant| puts constant end end # Usage: explore_methods("hello") def explore_methods(obj) methods = { instance: obj.methods - Object.methods, inherited: obj.methods & Object.methods, singleton: obj.singleton_methods } methods.each do |category, method_list| puts "#{category.to_s.capitalize} methods:" method_list.sort.each { |method| puts " #{method}" } puts end end # Usage: show_method_source(Array, :map) def show_method_source(obj, method_name) require 'pry' obj.method(method_name).source.display end # Usage: list_classes def list_classes Object.constants .select { |c| Object.const_get(c).is_a? Class } .sort .each { |klass| puts klass } end # Usage: method_location(Array, :map) def method_location(obj, method_name) file, line = obj.method(method_name).source_location puts "Defined in #{file}:#{line}" end # Usage: subclasses_of(ActiveRecord::Base) def subclasses_of(klass) ObjectSpace.each_object(Class).select { |k| k < klass } end def track_changes(target, method_name) original_value = target.send(method_name.to_s.sub('=', '')) puts "Starting to track changes to #{target}.#{method_name}" puts "Initial value: #{original_value.class}" trace = TracePoint.new(:line) do |tp| #next unless tp.method_id.to_s == method_name.to_s && tp.self.instance_of?(target.class) && tp.self == target next unless tp.self.instance_of?(target.class) && tp.self == target && tp.method_id.to_s.include?(method_name.to_s.sub('=', '')) current_value = target.send(method_name.to_s.sub('=', '')) if current_value != original_value puts "\nChange detected in #{target}.#{method_name}:" puts " From: #{original_value.class}" puts " To: #{current_value.class}" puts " At: #{tp.path}:#{tp.lineno}" puts " Backtrace:" puts caller[0..5].map { |line| " #{line}" } puts '-'*60 original_value = current_value end end trace.enable puts "Tracking enabled. Run 'trace.disable' to stop tracking." trace # Return the trace object so it can be disabled later end def track_method(klass, method_name, process=nil) trace = TracePoint.new(:call) do |tp| next unless tp.method_id.to_s == method_name.to_s next unless (klass.is_a?(Class) ? tp.self.is_a?(klass) : tp.self == klass) puts '-'*20 puts "#{tp.path}:#{tp.lineno}" puts "#{tp.defined_class}##{tp.method_id}" if tp.defined_class process.call if process end trace.enable if block_given? yield trace.disable else puts "Tracking enabled. Run 'trace.disable' to stop tracking." end trace # Return the trace object so it can be disabled later end 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)