0.0
No commit activity in last 3 years
No release in over 3 years
Extensions to the Proc class to support source extraction and comparison.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.10
~> 0.7
~> 2.13
~> 10.0
~> 3.0
~> 1.1
~> 0.30
~> 0.9

Runtime

~> 0.5
 Project Readme

Gem Version Build Status Code Climate Coverage Status

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.