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 # => true
You 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 # => true
Proc 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.3
The 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.3
The 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.3
The 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 # => false
The 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) # => true
If 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) # => false
If 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) # => false
Ruby 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.