Cognito Broadcast
5 Pry Features Every Ruby Developer Should Know
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.
Discovering available methods
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
Learning without documentation
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:
- We can convert CSS selectors into XPaths
- We can search XML documents with
#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!