Những công dụng "ẩn" của pry không phải ai cũng biết
Bài đăng này đã không được cập nhật trong 7 năm
Pry là một công cụ nổi tiếng mà bất cứ lập trình viên Ruby nào cũng biết. Cách sử dụng rất đơn giản, chỉ cần thêm dòng lệnh binding.pry
vào bất cứ đoạn code nào, chương trình sẽ dừng lại khi đọc đến đoạn code đó, và ta có thể sử dụng pry console như sau:
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>)
Nhưng pry không chỉ có vậy, nó còn cung cấp những công cụ khác giúp cho việc tìm hiểu về code được chủ động và hiệu quả hơn. Dưới đây là một số tính năng hỗ trợ của pry mà một lập trình viên nên biết:
Liệt kê các method khả dụng
Pry console cung cấp một lệnh ls
có khả năng liệt kê các hàm và biến khả dụng trong scope hiện tại. Ví dụ với pry console hiện lên ở ví dụ trên, lệnh ls
sẽ in ra:
> (#<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
Đây là một danh sách liệt kê các hàm khả dụng trong scope hiện tại, được nhóm theo các class và module định nghĩa hàm đó. Ở phía dưới là danh sách các biến instance và local. Nhờ đó ta có thể nắm được sơ bộ vai trò và nhiệm vụ của đoạn code đang debug.
Lệnh ls
còn cho phép ta đào sâu vào các phần khác của scope. Ta có thể thêm tùy chọn -locals
, hay viết tắt -l
để xem tên của các biến local cùng với giá trị hiện tại của chúng:
> (#<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
Tìm hiểu về code khi không có documentation
Pry cung cấp công cụ hỗ trợ việc tìm kiếm và liệt kê các hàm của một namespace bất kỳ. Ví dụ, nếu muốn tìm các hàm liên quan đến xử lý xpath
của Nokogiri
, ta dùng lệnh 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#xpath_at
Nokogiri::XML::Searchable#xpath_query_from_css_rule
Từ kết quả tìm kiếm ta có thể học được một số điều khá thú vị:
- Ta có thể convert một CSS selector thành XPath
- Ta có thể search trên một XML document với hàm #xpath và #xpath_at...
Nếu muốn tìm hiểu thêm và nắm được chính xác cách sử dụng một hàm ta có thể sử dụng lệnh stat
:
> 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
Thậm chí ta có thể thấy rõ được phương thức hoạt động của hàm với lệnh 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
Hoặc ta có thể xem doc của hàm nếu có với lệnh show-doc
:
> show-doc Nokogiri::XML::Searchable#xpath
From: /dev/gems/ruby/2.4.1/gems/nokogiri-1.7.2/lib/nokogiri/xml/searchable.rb @ line 122:
Owner: Nokogiri::XML::Searchable
Visibility: public
Signature: xpath(*args)
Number of lines: 29
call-seq: xpath *paths, [namespace-bindings, variable-bindings, custom-handle-class]
Search this node for XPath paths. paths must be one or more XPath
queries.
node.xpath('.//title')
A hash of namespace bindings may be appended. For example:
node.xpath('.//foo:name', {'foo' => 'http://example.org'})
node.xpath('.//xmlns:name', node.root.namespace)
A hash of variable bindingd may also be appended to namespace bindings. For example:
node.xpath('.//address[@domestic=$value]', nil, {:value => 'Yes'})
Custom XPath functions may also be defined. To define custom
functions create a class and implement the function you want
to define. The first argument to the method will be the
current matching NodeSet. Any other arguments are ones that
you pass in. Note that this class may appear anywhere in the
argument list. For example:
node.xpath('.//title[regex(., "\w+")]', Class.new {
def regex node_set, regex
node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
end
}.new)
>
Phía trên là những lệnh đơn giản và hữu ích khi debug với pry. Hy vọng bài viết này sẽ giúp ích được cho bạn trong công việc. Xin cảm ơn.
All rights reserved