Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.01 - inspect vars #3

Merged
merged 3 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 47 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,28 @@ When you like to know if and when a code point is reached, `ImLost.here` will he
ImLost.here
```

If you like to know the instance variables values of an object, use
`ImLost.vars`:

```ruby
ImLost.vars(self)
```

Or you can print the current local variables:

```ruby
ImLost.vars(binding)
```

See the [online help](https://rubydoc.info/gems/im-lost/ImLost) for more!

## Example

```ruby
require 'im-lost'

require_relative '../lib/im-lost'

class Foo
def self.create(value:) = new(value)

Expand All @@ -82,43 +99,40 @@ my_foo = Foo.create(value: :foo!)
ImLost.trace(my_foo)

my_foo.foo(1, key: :none)
ImLost.vars(my_foo)

my_foo.foo(2, :a, :b, :c, key: :some, name: :value)
ImLost.vars(my_foo)

my_foo.foo(3) { puts _1 }
ImLost.vars(my_foo)

# output will look like
# > Foo.create(:foo!)
# /projects/foo.rb:25
# > Foo.new(*)
# /projects/foo.rb:6
# < Foo.new(*)
# = #<Foo:0x0000000100902418 @value=:foo!>
# < Foo.create(:foo!)
# = #<Foo:0x0000000100902418 @value=:foo!>
# > Foo#foo(1, *[], :none, **{}, &nil)
# /projects/foo.rb:28
# > Foo#bar()
# /projects/foo.rb:15
# < Foo#bar()
# = :bar
# < Foo#foo(1, *[], :none, **{}, &nil)
# = "1-none-[]-{}-bar"
# > Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
# /projects/foo.rb:29
# > Foo#bar()
# /projects/foo.rb:15
# < Foo#bar()
# = :bar
# < Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
# = "2-some-[a,b,c]-{:name=>:value}-bar"
# > Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000100900578 /projects/foo.rb:30>)
# /projects/foo.rb:30
# > Foo#bar()
# /projects/foo.rb:15
# < Foo#bar()
# = :bar
# 3--[]-{}-bar
# < Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000100900578 /projects/foo.rb:30>)
# = nil
# > Foo.create(:foo!)
# /projects/foo.rb25
# > Foo.new(*)
# /projects/foo.rb6
# < Foo.new(*)
# = #<Foo:0x0000000100ab1188 @value=:foo!>
# < Foo.create(:foo!)
# = #<Foo:0x0000000100ab1188 @value=:foo!>
# > Foo#foo(1, *[], :none, **{}, &nil)
# /projects/foo.rb28
# > Foo#bar()
# /projects/foo.rb15
# < Foo#bar()
# = :bar
# < Foo#foo(1, *[], :none, **{}, &nil)
# = "1-none-[]-{}-bar"
# = /projects/foo.rb29
# instance variables:
# @value: "1-none-[]-{}-bar"
# = /projects/foo.rb32
# instance variables:
# @value: "2-some-[a,b,c]-{:name=>:value}-bar"
# = /projects/foo.rb35
# instance variables:
# @value: "3--[]-{}-bar"
```

See [examples dir](./examples) for more…
Expand Down
63 changes: 30 additions & 33 deletions examples/foo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,37 @@ def bar = :bar
ImLost.trace(my_foo)

my_foo.foo(1, key: :none)
ImLost.vars(my_foo)

my_foo.foo(2, :a, :b, :c, key: :some, name: :value)
ImLost.vars(my_foo)

my_foo.foo(3) { puts _1 }
ImLost.vars(my_foo)

# output will look like
# > Foo.create(:foo!)
# /projects/foo.rb:25
# > Foo.new(*)
# /projects/foo.rb:6
# < Foo.new(*)
# = #<Foo:0x0000000100902418 @value=:foo!>
# < Foo.create(:foo!)
# = #<Foo:0x0000000100902418 @value=:foo!>
# > Foo#foo(1, *[], :none, **{}, &nil)
# /projects/foo.rb:28
# > Foo#bar()
# /projects/foo.rb:15
# < Foo#bar()
# = :bar
# < Foo#foo(1, *[], :none, **{}, &nil)
# = "1-none-[]-{}-bar"
# > Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
# /projects/foo.rb:29
# > Foo#bar()
# /projects/foo.rb:15
# < Foo#bar()
# = :bar
# < Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
# = "2-some-[a,b,c]-{:name=>:value}-bar"
# > Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000100900578 /projects/foo.rb:30>)
# /projects/foo.rb:30
# > Foo#bar()
# /projects/foo.rb:15
# < Foo#bar()
# = :bar
# 3--[]-{}-bar
# < Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000100900578 /projects/foo.rb:30>)
# = nil
# > Foo.create(:foo!)
# /projects/foo.rb25
# > Foo.new(*)
# /projects/foo.rb6
# < Foo.new(*)
# = #<Foo:0x0000000100ab1188 @value=:foo!>
# < Foo.create(:foo!)
# = #<Foo:0x0000000100ab1188 @value=:foo!>
# > Foo#foo(1, *[], :none, **{}, &nil)
# /projects/foo.rb28
# > Foo#bar()
# /projects/foo.rb15
# < Foo#bar()
# = :bar
# < Foo#foo(1, *[], :none, **{}, &nil)
# = "1-none-[]-{}-bar"
# = /projects/foo.rb29
# instance variables:
# @value: "1-none-[]-{}-bar"
# = /projects/foo.rb32
# instance variables:
# @value: "2-some-[a,b,c]-{:name=>:value}-bar"
# = /projects/foo.rb35
# instance variables:
# @value: "3--[]-{}-bar"
67 changes: 63 additions & 4 deletions lib/im-lost.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# frozen_string_literal: true

# If you have overlooked something again and don't really understand what your
# code is doing. If you have to maintain this application but can't really find
# your way around and certainly can't track down that stupid error. If you feel
# lost in all that code, here's the gem to help you out!
#
# ImLost helps you by analyzing function calls of objects, informing you about
# exceptions and logging your way through your code. In short, ImLost is your
# debugging helper!
#
module ImLost
class << self
#
Expand Down Expand Up @@ -226,6 +235,28 @@ def untrace_all!
self
end

#
# Inspect internal variables.
#
# @overload vars(binding)
# Inspect local variables of given Binding.
# @param binding [Binding] which local variables should be print
# @return [self] itself
#
# @overload vars(object)
# Inspect instance variables of given object.
# @param object [Object] which instance variables should be print
# @return [Object] the given object
#
def vars(object)
traced = @trace.delete(object.__id__)
return _local_vars(object) if object.is_a?(Binding)
return unless object.respond_to?(:instance_variables)
_vars(object, Kernel.caller_locations(1, 1)[0])
ensure
@trace[traced] = 1 if traced
end

protected

def as_sig(prefix, info, args)
Expand Down Expand Up @@ -270,6 +301,34 @@ def _trace_all_b(args)
ensure
ids.each { @trace.delete(_1) }
end

def _vars(obj, location)
@output.puts("= #{location.path}:#{location.lineno}")
vars = obj.instance_variables
if vars.empty?
@output.puts(' <no instance variables defined>')
else
@output.puts(' instance variables:')
vars.sort!.each do |name|
@output.puts(" #{name}: #{obj.instance_variable_get(name).inspect}")
end
end
obj
end

def _local_vars(binding)
@output.puts("= #{binding.source_location.join(':')}")
vars = binding.local_variables
if vars.empty?
@output.puts(' <no local variables>')
else
@output.puts(' local variables:')
vars.sort!.each do |name|
@output.puts(" #{name}: #{binding.local_variable_get(name).inspect}")
end
end
self
end
end

ARG_SIG = { rest: '*', keyrest: '**', block: '&' }.compare_by_identity.freeze
Expand All @@ -283,12 +342,12 @@ def _trace_all_b(args)

@trace_calls = [
TracePoint.new(:c_call) do |tp|
next unless @trace.key?(tp.self.__id__)
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
@output.puts(as_sig('>', tp, tp.parameters.map { ARG_SIG[_1[0]] || '?' }))
@output.puts(" #{tp.path}:#{tp.lineno}") if @caller_locations
end,
TracePoint.new(:call) do |tp|
next unless @trace.key?(tp.self.__id__)
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
ctx = tp.binding
@output.puts(
as_sig(
Expand All @@ -308,12 +367,12 @@ def _trace_all_b(args)

@trace_results = [
TracePoint.new(:c_return) do |tp|
next unless @trace.key?(tp.self.__id__)
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
@output.puts(as_sig('<', tp, tp.parameters.map { ARG_SIG[_1[0]] || '?' }))
@output.puts(" = #{tp.return_value.inspect}")
end,
TracePoint.new(:return) do |tp|
next unless @trace.key?(tp.self.__id__)
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
ctx = tp.binding
@output.puts(
as_sig(
Expand Down
2 changes: 1 addition & 1 deletion lib/im-lost/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

module ImLost
# The version number of the gem.
VERSION = '1.0.0'
VERSION = '1.0.1'
end
Loading
Loading