I'm creating a module for a deck of cards. I want the Deck object to be able to accept another implementation of the shuffle method I have written below.
I was originally thinking that my shuffle method should accept a parameter that is any object that responds to shuffle. Is that a good approach here?
I'm not sure exactly how to approach this in Ruby.
module PlayingCards
class Deck
RANKS = [*2..10, 'Jack', 'Queen', 'King', 'Ace']
SUITS = %w{ Clubs Diamonds Hearts Spades }
attr_accessor :cards, :discarded
def initialize(options={})
#cards = []
#discarded = []
options[:number_decks] ||= 1
options[:number_decks].times do
(RANKS).product(SUITS).each do |rank, suit|
#cards << Card.new(rank, suit)
end
end
end
def shuffle()
cards.push(*discarded).shuffle!
discarded = []
self
end
end
end
This is the hand class that is responsible for drawing cards from the deck and also folding a hand.
module PlayingCards
class Hand
attr_accessor :deck, :draw_count, :cards, :discarded
def initialize(args = {})
#deck = args[:deck]
#discarded = args[:deck].discarded
#draw_count = args[:draw_count]
#cards = []
end
def draw
draw_count.times do
cards.push(deck.cards[0])
deck.cards.shift
end
cards
end
def fold
discarded.push(cards).flatten!
end
end
end
I want the Deck object to be able to accept another implementation of the shuffle method I have written below.
There are a few ways to implement this. There's no single right answer. Here's a few techniques:
Just define multiple methods:
def shuffle
cards.push(*discarded).shuffle!
discarded = []
self
end
# For example
def shuffle_before_replacing
cards.shuffle!
cards.push(*discarded)
discarded = []
self
end
Define a higher order method, for example:
SHUFFLE_MODES = {
standard: ->(cards, discarded) { cards.push(*discarded).shuffle },
# ...
}
def shuffle(mode: :standard)
cards = SHUFFLE_MODES.fetch(mode).call(cards, discarded)
discarded = []
self
end
Inject a dependency to perform the shuffling, for example:
def shuffle(shuffler: Shuffler::Standard)
shuffler = shuffler.new(cards, discarded)
shuffler.shuffle
cards = shuffler.cards
shuffler = shuffler.discarded
self
end
# ...
module Shuffler
class Base
attr_reader :cards, :discarded
def initialize(cards, discarded)
#cards = cards
#discarded = discarded
end
end
end
module Shuffler
class Standard < Base
def shuffle
#cards.push(*discarded).shuffle
#discarded = []
self
end
end
end
module Shuffler
class BeforeReplacing < Base
def shuffle
#cards.shuffle!
#cards.push(*discarded)
#discarded = []
self
end
end
end
end
One main benefits of this third approach is that you can define Shufflers independently to the Deck class - so for example, perhaps you'll eventually have multiple types of Deck that can each use the Shuffler interface in different ways. (For example, maybe you'll want to shuffle different things, or shuffle multiple times.)
Likewise, you can also test the Shufflers independently to the Deck. This works both ways; you can also now test the Deck independently to the Shuffler (by passing a mock object into the Deck#shuffle method).
This technique is the most advanced of the three, and is something I'd only usually expect an experienced developer to fully utilise, in more complex scenarios. It's hard to say whether such an abstraction is even with the effort yet in your case, given the limited information I have!
All code above is untested, so may not be spot on, but hopefully this gives you some inspiration.
Related
Let's say i have two classes
car class
class Car
include Comparable
attr_reader :wheel
def initialize(wheel)
#wheel = wheel
end
end
big car class
class BigCar
include Comparable
attr_reader :wheel, :big_car
def initialize(wheel)
#wheel = wheel
#size = ["big", "truck", "monster"].sample
end
end
generate array of them
cars = []
4.times do |x|
car = Car.new(x)
cars << car
end
big_cars = []
3.times do |x|
big_car = BigCar.new(x)
big_cars << big_car
end
i want to do
cars - big_cars
then i want it to result 1 car left, because it 4 - 3 = 1
but instead of 1, it returns all car.
i want to minus operator compare the wheel variable between two array.
so i add method in Car class
def <=>(other)
car.wheel <=> other.wheel
end
but it does not works.
What's the right way to do it?
thanks
As cars is an array, then the method you should be looking at is Array#-.
You could create a new class that holds cars without making a distinction whether they're big or not, just so they can be compared by their wheel.
class Cars
attr_reader :cars
def initialize(cars)
#cars = cars
end
def -(other)
cars.each_with_object([]) do |car, arr|
other.cars.each do |another_car|
arr.push(car) if car.wheel == another_car.wheel
end
end
end
end
big_cars = 3.times.map { |n_of_wheels| BigCar.new(n_of_wheels) }
# [#<Car:0x00007f92171ab750 #wheel=0>, #<Car:0x00007f92171ab6b0 #wheel=1>, #<Car:0x00007f92171ab688 #wheel=2>, #<Car:0x00007f92171ab660 #wheel=3>]
cars = 4.times.map { |n_of_wheels| Car.new(n_of_wheels) }
# [#<BigCar:0x00007f92171ab598 #wheel=0, #size="truck">, #<BigCar:0x00007f92171ab3b8 #wheel=1, #size="monster">, #<BigCar:0x00007f92171ab110 #wheel=2, #size="truck">]
Cars.new(big_cars) - Cars.new(cars)
# [#<BigCar:0x00007f92171afb48 #wheel=0, #size="monster">, #<BigCar:0x00007f92171af9b8 #wheel=1, #size="monster">, #<BigCar:0x00007f92171af8c8 #wheel=2, #size="truck">]
You don't really need the new class, you could just use the body of Cars#- extracting the variables it depends on.
And the method name doesn't necessarily have to be -, it can be any other (like diff, difference, compare_by_wheels, etc). It just gives a quick idea on what it does.
From the docs of Array#-:
items are compared using eql?
By including Comparable and implementing <=>, you only get ==, but not eql?. You have to add the latter yourself, e.g. as an alias for ==:
class Car
include Comparable
attr_reader :wheel
def initialize(wheel)
#wheel = wheel
end
def <=>(other)
self.wheel <=> other.wheel
end
alias eql? ==
end
Note that in order to get Array#- working, you just need eql?, i.e. a reduced version could look like this: (without Comparable)
class Car
attr_reader :wheel
def initialize(wheel)
#wheel = wheel
end
def eql?(other)
self.wheel == other.wheel
end
end
With both of the above, you'd get your expected result:
cars = Array.new(4) { |x| Car.new(x) }
big_cars = Array.new(3) { |x| BigCar.new(x) }
cars - big_cars
#=> [#<Car:0x00007fd0908cd710 #wheel=3>]
You probably want to implement eql? for BigCar, too. Or maybe make BigCar a subclass of Car and inherit its methods.
For your first question you want to compare the lengths of those arrays, which would look like this
cars.length - big_cars.length
because length gives you the number of items in the array.
Regarding the second Question, could you explain the expected output?
I'm trying to wrap my head around delegation vs. inheritance so I'm manually delegating a version of Array. One of the specific reasons I read to do this is because when you use things like enumerables, your returned value on the inherited methods reverts back to the parent class (i.e. Array). So I did this:
module PeepData
# A list of Peeps
class Peeps
include Enumerable
def initialize(list = [])
#list = list
end
def [](index)
#list[index]
end
def each(...)
#list.each(...)
end
def reverse
Peeps.new(#list.reverse)
end
def last
#list.last
end
def join(...)
#list.join(...)
end
def from_csv(csv_table)
#list = []
csv_table.each { |row| #list << Peep.new(row.to_h) }
end
def include(field, value)
Peeps.new(select { |row| row[field] == value })
end
def exclude(field, value)
Peeps.new(select { |row| row[field] != value })
end
def count_by_field(field)
result = {}
#list.each do |row|
result[row[field]] = result[row[field]].to_i + 1
end
result
end
protected
attr_reader :list
end
end
When I instantiate this, my include and exclude function great and return a Peeps class but when using an enumerable like select, it returns Array, which prevents me from chaining further Peeps specific methods after the select. This is exactly what I'm trying to avoid with learning about delegation.
p = Peeps.new
p.from_csv(csv_generated_array_of_hashes)
p.select(&:certified?).class
returns Array
If I override select, wrapping it in Peeps.new(), I get a "SystemStackError: stack level too deep". It seems to be recursively burying the list deeper into the list during the select enumeration.
def select(...)
Peeps.new(#list.select(...))
end
Any help and THANKS!
I would recommend using both Forwardable and Enumerable. Use Forwardable to delegate the each method to your list (to satisfy the Enumerable interface requirement), and also forward any Array methods you might want to include that are not part of the Enumerable module, such as size. I would also suggest not overriding the behavior of select as it is supposed to return an array and would at the very least lead to confusion. I would suggest something like the subset provided below to implement the behavior you are looking for.
require 'forwardable'
class Peeps
include Enumerable
extend Forwardable
def_delegators :#list, :each, :size
def initialize(list = [])
#list = list
end
def subset(&block)
selected = #list.select(&block)
Peeps.new(selected)
end
protected
attr_reader :list
end
Example usage:
peeps = Peeps.new([:a,:b,:c])
subset = peeps.subset {|s| s != :b}
puts subset.class
peeps.each do |peep|
puts peep
end
puts peeps.size
puts subset.size
produces:
Peeps
a
b
c
3
2
I think that if Peeps#select will return an Array, then it is OK to include Enumerable. But, you want Peeps#select to return a Peeps. I don't think you should include Enumerable. It's misleading to claim to be an Enumerable if you don't conform to its interface. This is just my opinion. There is no clear consensus on this in the ecosystem. See "Examples from the ecosystem" below.
If we accept that we cannot include Enumerable, here's the first implementation that comes to my mind.
require 'minitest/autorun'
class Peeps
ARRAY_METHODS = %i[flat_map map reject select]
ELEMENT_METHODS = %i[first include? last]
def initialize(list)
#list = list
end
def inspect
#list.join(', ')
end
def method_missing(mth, *args, &block)
if ARRAY_METHODS.include?(mth)
self.class.new(#list.send(mth, *args, &block))
elsif ELEMENT_METHODS.include?(mth)
#list.send(mth, *args, &block)
else
super
end
end
end
class PeepsTest < Minitest::Test
def test_first
assert_equal('alice', Peeps.new(%w[alice bob charlie]).first)
end
def test_include?
assert Peeps.new(%w[alice bob charlie]).include?('bob')
end
def test_select
peeps = Peeps.new(%w[alice bob charlie]).select { |i| i < 'c' }
assert_instance_of(Peeps, peeps)
assert_equal('alice, bob', peeps.inspect)
end
end
I don't normally use method_missing, but it seemed convenient.
Examples from the ecosystem
There doesn't seem to be a consensus on how strictly to follow interfaces.
ActionController::Parameters used to inherit Hash. Inheritance ceased in Rails 5.1.
ActiveSupport::HashWithIndifferentAccess still inherits Hash.
As mentioned in the other answer, this isn't really proper usage of Enumerable. That said, you could still include Enumerable and use some meta-programming to override the methods that you want to be peep-chainable:
module PeepData
class Peeps
include Enumerable
PEEP_CHAINABLES = [:map, :select]
PEEP_CHAINABLES.each do |method_name|
define_method(method_name) do |&block|
self.class.new(super(&block))
end
end
# solution for select without meta-programming looks like this:
# def select
# Peeps.new(super)
# end
end
end
Just so you know, this really has nothing to do with inheritance vs delegation. If Peeps extended Array, you would have the exact same issue, and the exact solution above would still work.
I have an empty object that accepts calculated values for each factor. The method is readable but long and ugly. What is a DRY way of doing this?
class ReadingScore
def initialize(reading, score)
#reading = reading
#score = score
end
def assign_scoring_factors
#score.heart_rate_factor = heart_rate_factor
#score.systolic_pressure_factor = systolic_pressure_factor
#score.diastolic_pressure_factor = diastolic_pressure_factor
#score.mean_pressure_factor = mean_pressure_factor
#score.signal_minimum_factor = signal_minimum_factor
#score.signal_average_factor = signal_average_factor
…
end
def heart_rate_factor
#reading.heart_rate && (1..10).include?(#reading.heart_rate) ? 0 : 10
end
…
end
Update
The overall purpose of this class is to calculate a score of a reading. I can’t provide all the code because it is a proprietary algorithm for a medical device.
But basically there are n factors of a #reading that are calculated and then saved to a #score object associated with the #reading. The sum of the factors is also calculated as a total on the #score object. The #score object looks like the following:
#score=
#<Score:0x007faa0b33ec50
#attributes=
{"id"=>42,
"reading_id"=>42,
"sum_of_factors"=>10,
"heart_rate_factor"=>10,
"another_factor"=>0,
"another_factor"=>0}
This seems to be the best option so far. The first answer to the question started me on this route, but the poster seems to have removed it…
def assign_factors_to_score
factors.each do |factor|
#score.public_send("#{factor}=", self.public_send(factor))
end
end
def factors
%i{factor_a factor_b factor_c factor_d}
end
You can automatically populate an array of factors using method_added. This combines nicely with dynamic assignment of factors as in your answer.
class ReadingScore
#factors = []
def self.method_added meth
#factors << meth if meth =~ /_factor\Z/
end
def self.factors
#factors
end
end
Note that these are class methods, so you would need to use self.class.factors when using this in an instance method.
Here is a full implementation in case you do not see how to integrate this code.
You could use delegate
class ReadingScore
extend Forwardable
delegate [:heart_rate_factor=, :systolic_pressure_factor=,:diastolic_pressure_factor=,
:mean_pressure_factor=,:signal_minimum_factor=,:signal_average_factor=] => :#score
def initialize
#score = Score.new
end
def assign_scoring_factors
%w(heart_rate_factor systolic_pressure_factor diastolic_pressure_factor mean_pressure_factor signal_minimum_factor signal_average_factor).each do |meth|
self.send("#{meth}=",self.send(meth))
end
self
end
end
but I agree with others that rethinking the whole design might be better here.
You could also use tap but the code will look fairly similar to what you have now.
Also I have no idea what a Score looks like internally because it seems like it would be better to place this logic inside the Score or Reading and pass all of this to a method or initializer of Score. e.g.
class ReadingScore
def intialize(reading)
#reading = Reading.new(reading)
#score = Score.new(#reading)
end
end
class Reading
#...
def heart_rate_score
heart_rate && (1..10).include?(#reading.heart_rate) ? 0 : 10
end
def systolic_pressure_score
#logic
end
def diastolic_pressure_score
#logic
end
def mean_pressure_score
#logic
end
def signal_minimum_score
#logic
end
def signal_average_score
#logic
end
end
class Score
attr_accessor :heart_rate_factor,:systolic_pressure_factor,:diastolic_pressure_factor,
:mean_pressure_factor,:signal_minimum_factor,:signal_average_factor
def initialize(reading)
factorialize(reading)
self
end
private
def factorialize(reading)
%w(heart_rate systolic_pressure diastolic_pressure mean_pressure signal_minimum signal_average) do |meth|
self.send("#{meth}_factor=",reading.send("#{meth}_score")
end
end
end
This way your logic is centralized in Score and Reading and can be avoided in ReadingScore. This will make the code easier to trace and will clean up the original class.
you can do it like this, if you insist:
def assign_scoring_factors
%w(heart_rate systolic_pressure diastolic_pressure mean_pressure signal_minimum signal_average).each |f| do
eval("#score.#{f}.factor = #{f}.factor")
end
end
but this isn't what I'd do. I'd either leave it moist, or just use a map.
Say I have the following class:
class Cashier
def purchase(amount)
(#purchases ||= []) << amount
end
def total_cash
(#purchases || []).inject(0) {|sum,amount| sum + amount}
end
end
This is for learning purposes only, please ignore how unrealistic this may be.
Now in general, the total_cash could be an expensive call to loop through all the items.
I want to know how I can call .inject ONLY if the #purchases variable is dirty i.e. there was something modified.
How would my class be modified to do this?
The simplest approach would be to maintain another variable to indicate whether or not #purchases is dirty. For example:
class Cashier
def initialize(*args)
# init #purchases and #total_cash
#is_purchases_dirty = false
end
def purchase(amount)
(#purchases ||= []) << amount
#is_purchases_dirty = true
end
def total_cash
return #total_cash unless #is_purchases_dirty
#is_purchases_dirty = false
#total_cash = (#purchases || []).inject(0) {|sum,amount| sum + amount}
return #total_cash
end
end
A cleaner/simpler approach may be to calculate #total_cash each time the setter is called for purchases. However, this means that you need to always use the setter, even within your class. It also means that you will be "hiding" an expensive operation inside of a setter method. You can decide which one you like better.
class Cashier
def purchase(amount)
(#purchases ||= []) << amount
#total_cash = (#purchases || []).inject(0) {|sum,amount| sum + amount}
end
def total_cash
#total_cash
end
end
I would also recommend against your naming scheme for an expensive operation. I would rename total_cash to something like calc_total_cash in order to tell users of your API that this is a relatively expensive call as opposed to a simple getter/setter.
You can take this a step further than the other answers if you wanted. Rather than changing your code to only recalculate when necessary, you can write the code that changes your code. Everybody loves a bit of metaprogramming.
Here's some code that takes the name of a method that performs a potentially long calculation, and a list of names of methods that when called invalidate any previous calculation, and writes the code to wrap the methods and only perform the calculation if necessary, returning the stored value if not.
module ExpensiveCalculation
def recalc_only_if_necessary(meth, *mutators)
aliased_method_name = "__#{meth.object_id}__"
value = "#__#{meth.object_id}_value__"
dirty_flag = "#__#{meth.object_id}_dirty__"
module_eval <<-EOE
alias_method :#{aliased_method_name}, :#{meth}
private :#{aliased_method_name}
def #{meth}(*args, &blk)
#{dirty_flag} = true unless defined? #{dirty_flag}
return #{value} unless #{dirty_flag}
#{value} = #{aliased_method_name}(*args, &blk)
#{dirty_flag} = false
#{value}
end
EOE
mutators.each do |mutator|
aliased_mutator = "__#{meth.object_id}_#{mutator.object_id}__"
module_eval <<-EOE
alias_method :#{aliased_mutator}, :#{mutator}
private :#{aliased_mutator}
def #{mutator}(*args, &blk)
#{dirty_flag} = true
#{aliased_mutator}(*args, &blk)
end
EOE
end
end
# this hook is used to make the new method
# private to the extended class.
def self.extend_object(obj)
super
obj.private_class_method :recalc_only_if_necessary
end
end
By making this available inside your class definition, you can wrap one or many methods easily without changing your existing code:
class Cashier
extend ExpensiveCalculation
def purchase(amount)
(#purchases ||= []) << amount
end
def total_cash
(#purchases || []).inject(0) {|sum,amount| sum + amount}
end
recalc_only_if_necessary :total_cash, :purchase
end
It might not make sense to do something like this if you just want to change one method, but if you have several that you want to change some way techniques like this can be pretty useful.
In the simplest case, you could define an instance variable for the thing you want to mark as dirty. Set it to true when the variable is modified (in your purchase method).
Check for the value in total_cash; if so, use a cached version of the total. Otherwise, compute the new value and store it in the cache.
class Cashier
def purchase(amount)
#purchases_dirty = true
(#purchases ||= []) << amount
end
def total_cash
#total_cash = (#purchases || []).inject(0) do |sum,amount|
sum + amount
end if (#purchases_dirty || #total_cash.nil?)
#purchases_dirty = false
#total_cash
end
end
I have an object Results that contains an array of result objects along with some cached statistics about the objects in the array. I'd like the Results object to be able to behave like an array. My first cut at this was to add methods like this
def <<(val)
#result_array << val
end
This feels very c-like and I know Ruby has better way.
I'd also like to be able to do this
Results.each do |result|
result.do_stuff
end
but am not sure what the each method is really doing under the hood.
Currently I simply return the underlying array via a method and call each on it which doesn't seem like the most-elegant solution.
Any help would be appreciated.
For the general case of implementing array-like methods, yes, you have to implement them yourself. Vava's answer shows one example of this. In the case you gave, though, what you really want to do is delegate the task of handling each (and maybe some other methods) to the contained array, and that can be automated.
require 'forwardable'
class Results
include Enumerable
extend Forwardable
def_delegators :#result_array, :each, :<<
end
This class will get all of Array's Enumerable behavior as well as the Array << operator and it will all go through the inner array.
Note, that when you switch your code from Array inheritance to this trick, your << methods would start to return not the object intself, like real Array's << did -- this can cost you declaring another variable everytime you use <<.
each just goes through array and call given block with each element, that is simple. Since inside the class you are using array as well, you can just redirect your each method to one from array, that is fast and easy to read/maintain.
class Result
include Enumerable
def initialize
#results_array = []
end
def <<(val)
#results_array << val
end
def each(&block)
#results_array.each(&block)
end
end
r = Result.new
r << 1
r << 2
r.each { |v|
p v
}
#print:
# 1
# 2
Note that I have mixed in Enumerable. That will give you a bunch of array methods like all?, map, etc. for free.
BTW with Ruby you can forget about inheritance. You don't need interface inheritance because duck-typing doesn't really care about actual type, and you don't need code inheritance because mixins are just better for that sort of things.
Your << method is perfectly fine and very Ruby like.
To make a class act like an array, without actually inheriting directly from Array, you can mix-in the Enumerable module and add a few methods.
Here's an example (including Chuck's excellent suggestion to use Forwardable):
# You have to require forwardable to use it
require "forwardable"
class MyArray
include Enumerable
extend Forwardable
def initialize
#values = []
end
# Map some of the common array methods to our internal array
def_delegators :#values, :<<, :[], :[]=, :last
# I want a custom method "add" available for adding values to our internal array
def_delegator :#values, :<<, :add
# You don't need to specify the block variable, yield knows to use a block if passed one
def each
# "each" is the base method called by all the iterators so you only have to define it
#values.each do |value|
# change or manipulate the values in your value array inside this block
yield value
end
end
end
m = MyArray.new
m << "fudge"
m << "icecream"
m.add("cake")
# Notice I didn't create an each_with_index method but since
# I included Enumerable it knows how and uses the proper data.
m.each_with_index{|value, index| puts "m[#{index}] = #{value}"}
puts "What about some nice cabbage?"
m[0] = "cabbage"
puts "m[0] = #{m[0]}"
puts "No! I meant in addition to fudge"
m[0] = "fudge"
m << "cabbage"
puts "m.first = #{m.first}"
puts "m.last = #{m.last}"
Which outputs:
m[0] = fudge
m[1] = icecream
m[2] = cake
What about some nice cabbage?
m[0] = cabbage
No! I meant in addition to fudge
m.first = fudge
m.last = cabbage
This feels very c-like and I know Ruby
has better way.
If you want an object to 'feel' like an array, than overriding << is a good idea and very 'Ruby'-ish.
but am not sure what the each method
is really doing under the hood.
The each method for Array just loops through all the elements (using a for loop, I think). If you want to add your own each method (which is also very 'Ruby'-ish), you could do something like this:
def each
0.upto(#result_array.length - 1) do |x|
yield #result_array[x]
end
end
If you create a class Results that inherit from Array, you will inherit all the functionality.
You can then supplement the methods that need change by redefining them, and you can call super for the old functionality.
For example:
class Results < Array
# Additional functionality
def best
find {|result| result.is_really_good? }
end
# Array functionality that needs change
def compact
delete(ininteresting_result)
super
end
end
Alternatively, you can use the builtin library forwardable. This is particularly useful if you can't inherit from Array because you need to inherit from another class:
require 'forwardable'
class Results
extend Forwardable
def_delegator :#result_array, :<<, :each, :concat # etc...
def best
#result_array.find {|result| result.is_really_good? }
end
# Array functionality that needs change
def compact
#result_array.delete(ininteresting_result)
#result_array.compact
self
end
end
In both of these forms, you can use it as you want:
r = Results.new
r << some_result
r.each do |result|
# ...
end
r.compact
puts "Best result: #{r.best}"
Not sure I'm adding anything new, but decided to show a very short code that I wish I could have found in the answers to quickly show available options. Here it is without the enumerator that #shelvacu talks about.
class Test
def initialize
#data = [1,2,3,4,5,6,7,8,9,0,11,12,12,13,14,15,16,172,28,38]
end
# approach 1
def each_y
#data.each{ |x| yield(x) }
end
#approach 2
def each_b(&block)
#data.each(&block)
end
end
Lets check performance:
require 'benchmark'
test = Test.new
n=1000*1000*100
Benchmark.bm do |b|
b.report { 1000000.times{ test.each_y{|x| #foo=x} } }
b.report { 1000000.times{ test.each_b{|x| #foo=x} } }
end
Here's the result:
user system total real
1.660000 0.000000 1.660000 ( 1.669462)
1.830000 0.000000 1.830000 ( 1.831754)
This means yield is marginally faster than &block what we already know btw.
UPDATE: This is IMO the best way to create an each method which also takes care of returning an enumerator
class Test
def each
if block_given?
#data.each{|x| yield(x)}
else
return #data.each
end
end
end
If you really do want to make your own #each method, and assuming you don't want to forward, you should return an Enumerator if no block is given
class MyArrayLikeClass
include Enumerable
def each(&block)
return enum_for(__method__) if block.nil?
#arr.each do |ob|
block.call(ob)
end
end
end
This will return an Enumerable object if no block is given, allowing Enumerable method chaining