ProcSource Class
The gem includes the ProcSource class which provides
access to the proc extensions without monkey patching the Proc class itself.
You can create a ProcSource with either a proc as a parameter or by passing a block to ProcSource.
p = proc { |a| a.to_s }
ps1 = ProcSource.new p
ps2 = ProcSource.new { |b| b.to_s }You can use the raw_source method to return the original source and
the source method to return the sanitized version of the source.
ps1.source # => "proc { |a| a.to_s }"
ps1.raw_source # => "proc { |a| a.to_s }"
ps1.to_s # => "proc { |a| a.to_s }"
ps1.inspect # => "proc { |a| a.to_s }"
ps1 == ps2 # => false
ps1.match ps2 # => trueYou can create a ProcSource with no proc or with a nil proc and it will simply provide an empty string for source
raw_source, to_s and inspect. And two ProcSource objects created like this will be considered equal.
ps1 = ProcSource.new
ps2 = ProcSource.new nil
ps1.source # => ""
ps1.raw_source # => ""
ps1.to_s # => ""
ps1.inspect # => ""
ps1 == ps2 # => true
ps1.match ps2 # => trueProc Extensions
Extensions to Proc support source extraction and comparison.
Optionally methods can be added to the Proc class:
-
inspect: returns source code if it can be extracted -
source,raw_source: returns source code -
==: determines if two procs have exactly the same source code -
match,=~: determines if two procs have the source code allowing for different parameter names
The above methods are not automatically included into the Proc class.
You need to explicitly include modules included in this gem.
Note This gem uses the sourcify gem to extact proc source code. The sourcify gem
is no longer supported although it works as needed for the proc_extensions gem.
Installation
Add this line to your application's Gemfile:
gem 'proc_extensions'And then execute:
$ bundle
Or install it yourself as:
$ gem install proc_extensions
Usage
require proc_extensions
Extensions to the Proc class
inspect Method
The inspect methods is added to Proc when ProcExtensions::Inspect is included with Proc:
Proc.include ProcExtensions::Inspect # Ruby 2
Proc.send :include, ProcExtensions::Inspect # Ruby 1.9.3The inspect method will return the source code for the proc.
p = proc { |a| a.to_s }
l = lambda { |a| a.to_s }
p.inspect # => "proc { |a| a.to_s }"
l.inspect # => "lambda { |a| a.to_s }"If the source code cannot be extracted then the original Proc#inspect method will be called:
# Can't get source if multiple procs declared on the same line
p = proc { proc {} }
p.inspect # => "#<Proc:0x007fe72b879b90>"source Methods
The source and raw_source methods are added to Proc when ProcExtensions::Source is included with Proc:
Proc.include ProcExtensions::Source # Ruby 2
Proc.send :include, ProcExtensions::Source # Ruby 1.9.3The Proc#source method will return the source code for the Proc with
white space and comments removed. The raw_source method will return the original source.
p = proc { | a | a.to_s }
p.source # "proc { |a| a.to_s }"
p.raw_source # "proc { | a | a.to_s }"Lambda source will have the prefix 'lambda' rather than 'proc':
l = lambda { |a| a.to_s }
l.source # "lambda { |a| a.to_s }"If the source cannot be extracted then an exception will be raised by the sourcify gem.
match Methods
The match and =~ methods are added to Proc when ProcExtensions::Match is included with Proc:
Proc.include ProcExtensions::Match # Ruby 2
Proc.send :include, ProcExtensions::Match # Ruby 1.9.3The match(other) method will return true if the procs are the same proc or
if the two procs have the same source code. The =~ method is created as an alias for match.
proc1 = proc {}
proc2 = proc {}
proc3 = proc { |a| a.to_s }
proc1.match(proc2) # => true
proc1.match(proc3) # => false
proc1 =~ proc2 # => true
proc1 =~ proc3 # => falseThe source code for two procs are considered equal if they have the same body even with different parameter names:
proc1 = proc { |a| a.to_s }
proc2 = proc { |b| b.to_s }
proc1.match(proc2) # => trueIf the procs are created via &:method then they will
be considered equal if they reference the same method:
proc1 = proc(&:to_s)
proc2 = proc(&:to_s)
proc3 = proc(&:to_a)
proc1.match(proc2) # => true
proc1.match(proc3) # => falseIf the source code cannot be extracted from either proc then false will be returned:
# Can't get source if multiple procs declared on the same line
proc1 = proc { proc {} }
proc2 = proc { proc {} }
proc1.match(proc2) # => falseRuby Versions Supported
- 1.9.3
- 2.0
- 2.1
- 2.2
Development
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/dwhelan/proc_extensions. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.