Pry is a great tool for Ruby. You have probably used it by setting binding.pry
in the middle of your code like so:
From: lib/dry/types/hash/schema.rb @ line 58 Dry::Types::Hash::Schema#try:
40: def try(hash, &block)
41: success = true
42: output = {}
43:
44: begin
45: result = try_coerce(hash) do |key, member_result|
46: success &&= member_result.success?
47: output[key] = member_result.input
48:
49: member_result
50: end
51: rescue ConstraintError, UnknownKeysError, SchemaError => e
52: success = false
53: result = e
54: end
55:
56: binding.pry
57:
=> 58: if success
59: success(output)
60: else
61: failure = failure(output, result)
62: block ? yield(failure) : failure
63: end
64: end
> (#<Dry::Types::Hash::Weak>)
Pry is much more than a tool for setting a breakpoint though. It is a great tool for exploring code interactively.
Pry provides a command called ls
that lists methods and variables available in the current scope. In the code snippet above, the ls
command would print out the following:
> (#<Dry::Types::Hash::Weak>) ls
#<Dry::Equalizer:0x007fafd29f2b88>#methods:
hash
inspect
Dry::Equalizer::Methods#methods:
==
eql?
Dry::Types::Options#methods:
meta
pristine
with
Dry::Types::Builder#methods:
constrained
constrained_type
constructor
default
enum
optional
safe
|
Dry::Types::Definition#methods:
===
default?
name
options
primitive?
success
constrained?
failure
optional?
primitive
result
valid?
Dry::Types::Hash#methods:
permissive
schema
strict
strict_with_defaults
symbolized
weak
Dry::Types::Hash::Schema#methods:
[]
call
member_types
Dry::Types::Hash::Weak#methods:
try
instance variables:
@__args__
@member_types
@meta
@options
@primitive
locals:
block
e
failure
hash
output
result
success
This is a breakdown of all the methods available in the current scope, grouped by the class or module that owns that method. It also lists the available instance variables and local variables. This is a very powerful tool for quickly understanding the role and responsibility of the code you are debugging.
The ls
command also lets you drill down into different parts of the current scope. We can use ls --locals
to view the names of local variables alongside their current values:
> (#<Dry::Types::Hash::Weak>) ls -l
result = {
:name=> #<Dry::Types::Result::Failure
input=nil
error=#<Dry::Logic::Result:0x007fafd2cb98d0
@success=false,
@id=nil,
@serializer=#<Proc:0x01@lib/dry/logic/rule.rb:47>>>}
hash = {:name=>nil}
output = {:name=>nil}
success = false
block = nil
e = nil
failure = nil
Pry makes it easy to search for methods under a namespace. For example, if we wanted to find methods for handling xpaths with Nokogiri, we can use find-method
:
> find-method xpath Nokogiri
Nokogiri::CSS.xpath_for
Nokogiri::CSS::Node
Nokogiri::CSS::Node#to_xpath
Nokogiri::CSS::Parser
Nokogiri::CSS::Parser#xpath_for
Nokogiri::XML::Document
Nokogiri::XML::Document#implied_xpath_contexts
Nokogiri::XML::Node
Nokogiri::XML::Node#implied_xpath_contexts
Nokogiri::XML::NodeSet
Nokogiri::XML::NodeSet#xpath
Nokogiri::XML::NodeSet#implied_xpath_contexts
Nokogiri::XML::Searchable
Nokogiri::XML::Searchable#xpath
Nokogiri::XML::Searchable#at_xpath
Nokogiri::XML::Searchable#xpath_query_from_css_rule
We learn some interesting features from this list:
#xpath
and #xpath_at
If we want to learn more about how to precisely use one of these methods we can use the stat
command:
> stat Nokogiri::CSS.xpath_for
Method Information:
--
Name: xpath_for
Alias: None.
Owner: #<Class:Nokogiri::CSS>
Visibility: public
Type: Bound
Arity: -2
Method Signature: xpath_for(selector, options=?)
Source Location: /dev/gems/ruby/2.4.1/gems/nokogiri-1.7.2/lib/nokogiri/css.rb:22
If we wanted to learn how the method works, we can use show-source
:
> show-source Nokogiri::CSS.xpath_for
From: /dev/gems/ruby/2.4.1/gems/nokogiri-1.7.2/lib/nokogiri/css.rb @ line 22:
Owner: #<Class:Nokogiri::CSS>
Visibility: public
Number of lines: 3
def xpath_for(selector, options={})
Parser.new(options[:ns] || {}).xpath_for selector, options
end
We can also see nice, syntax highlighted code examples using show-doc
:
These handful of commands are a great daily resource for debugging and exploring new gems. Give it a try!