Permalink
Browse files

Syntax highligting is purty.

  • Loading branch information...
1 parent fd8fef0 commit 6697ead6250cc7126fd4b0e97e94aecda615ce45 @ernie committed Aug 20, 2012
Showing with 64 additions and 52 deletions.
  1. +60 −50 README.md
  2. +1 −0 equivalence.gemspec
  3. +3 −2 lib/equivalence.rb
View
110 README.md
@@ -8,25 +8,27 @@ to reuse, though, your code might be leaving your users perplexed.
Consider the following situation:
- class Awesomeness
- def initialize(level, description)
- @level = level
- @description = description
- end
-
- def declare_awesomeness
- puts "My awesomeness level is #{@level} (#{@description})!"
- end
- end
-
- awesome1 = Awesomeness.new(10, 'really awesome')
- awesome2 = Awesomeness.new(10, 'really awesome')
- awesome1.declare_awesomeness
- # => "My awesomeness level is 10 (really awesome)!"
- awesome2.declare_awesomeness
- # => "My awesomeness level is 10 (really awesome)!"
- [awesome1, awesome2].uniq.size # => 2
- awesome1 == awesome2 # => false
+```ruby
+class Awesomeness
+ def initialize(level, description)
+ @level = level
+ @description = description
+ end
+
+ def declare_awesomeness
+ puts "My awesomeness level is #{@level} (#{@description})!"
+ end
+end
+
+awesome1 = Awesomeness.new(10, 'really awesome')
+awesome2 = Awesomeness.new(10, 'really awesome')
+awesome1.declare_awesomeness
+# => "My awesomeness level is 10 (really awesome)!"
+awesome2.declare_awesomeness
+# => "My awesomeness level is 10 (really awesome)!"
+[awesome1, awesome2].uniq.size # => 2
+awesome1 == awesome2 # => false
+```
Surprised? You shouldn't be. Ruby's default implementation of object equality
considers objects equal only if they are the same object, *not* if they have the
@@ -35,20 +37,22 @@ same contents.
This probably isn't what you want for your Awesomeness class. To get equality
behaving as you'd expect, you need to do the following:
- class Awesomeness
- attr_reader :level, :description
+```ruby
+class Awesomeness
+ attr_reader :level, :description
- def hash
- [@level, @description].hash
- end
+ def hash
+ [@level, @description].hash
+ end
- def eql?(other)
- self.class == other.class &&
- self.level == other.level &&
- self.description == other.description
- end
- alias :== :eql?
- end
+ def eql?(other)
+ self.class == other.class &&
+ self.level == other.level &&
+ self.description == other.description
+ end
+ alias :== :eql?
+end
+```
Implementing the `==` method gets your comparison to return true, as expected,
and implementing `hash` and `eql?` gets `Array#uniq` to behave as expected, and
@@ -80,39 +84,43 @@ Or install it yourself as:
### Basic
+```ruby
class MySpiffyClass
extend Equivalence
equivalence :@my, :@instance, :@variables # , [...]
# Your spiffy class implementation
end
+```
You'll get the equality methods we "painstakingly" added above, without all that
pesky typing. If you don't implement reader methods (as above), Equivalence will
create some for you, with `protected` access (meaning only other objects within
MySpiffyClass's class hierarchy will be able to call them), since they're
-necessary for the `eql?` method to work). Defining your own readers? No problem,
+necessary for the `eql?` method to work. Defining your own readers? No problem,
Equivalence won't mess with them.
Let's re-visit the example from above.
- class Awesomeness
- extend Equivalence
- equivalence :@level, :@description
-
- def initialize(level, description)
- @level = level
- @description = description
- end
-
- def declare_awesomeness
- puts "My awesomeness level is #{@level} (#{@description})!"
- end
- end
+```ruby
+class Awesomeness
+ extend Equivalence
+ equivalence :@level, :@description
+
+ def initialize(level, description)
+ @level = level
+ @description = description
+ end
+
+ def declare_awesomeness
+ puts "My awesomeness level is #{@level} (#{@description})!"
+ end
+end
- awesome1 = Awesomeness.new(10, 'really awesome')
- awesome2 = Awesomeness.new(10, 'really awesome')
- [awesome1, awesome2].uniq.size # => 1
- awesome1 == awesome2 # => true
+awesome1 = Awesomeness.new(10, 'really awesome')
+awesome2 = Awesomeness.new(10, 'really awesome')
+[awesome1, awesome2].uniq.size # => 1
+awesome1 == awesome2 # => true
+```
Less hassle, same result.
@@ -125,7 +133,9 @@ case, you'll want your `hash` method to be defined with calls to the methods
instead of accessing the ivars directly, to get the expected results. Just omit
the leading @ in each parameter, like so:
- equivalence :level, :description
+```ruby
+equivalence :level, :description
+```
## Contributing
View
@@ -9,6 +9,7 @@ Gem::Specification.new do |gem|
gem.homepage = "http://github.com/ernie/equivalence"
gem.add_development_dependency 'rspec', '~> 2.11.0'
+ gem.add_development_dependency 'rake'
gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
View
@@ -6,7 +6,8 @@ module Equivalence
def equivalence(*args)
raise ArgumentError, 'At least one attribute is required.' if args.empty?
- method_names = args.map { |arg| arg.to_s.sub /^@/, '' }
+ args.map!(&:to_s)
+ method_names = args.map { |arg| arg.sub /^@/, '' }
__define_equivalence_hash_method(args)
__define_equivalence_attribute_readers(method_names)
@@ -16,7 +17,7 @@ def equivalence(*args)
def __define_equivalence_hash_method(ivar_or_method_names)
# Method names might be keywords. We'll want to prefix them with "self"
ivar_or_method_names = ivar_or_method_names.map do |name|
- name.to_s[0] == '@' ? name : "self.#{name}"
+ name.start_with?('@') ? name : "self.#{name}"
end
class_eval <<-EVAL, __FILE__, __LINE__

0 comments on commit 6697ead

Please sign in to comment.