How do I add 'each' method to Ruby object (or should I extend Array)?
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 <<
.
Possible to extend methods of Array in ruby?
Yes, this is possible.
class Array
def join_names
collect(&:name).join(", ")
end
end
But this makes it more likely that you code will have namespace collisions with other libraries that add methods to the Array class.
Ruby: How do I add methods to Object? (or simply Extend the object class)
# object.rb
class Object
def table_name
self.class.name.tableize
end
end
put it into /config/initializers
or into lib
folder (in this case you'll need to include it in ApplicationController
).
Ruby Extended Array class that supports full method chain
If you ever want to monkey-patch a core class but you think it's icky, you should remember that refinements are made just for this scenario.
module ArrayWithWord
refine Array do
def word
[*self[0..1],*self[-2..-1]].map(&:chr).join
end
end
end
class WordTest
using ArrayWithWord
# [].word works here
def self.sort_transform(a)
[
a.word,
a.sort.word,
a.sort_by(&:-@).word,
a.map(&:chr).sort.map(&:ord).word
].join ?-
end
end
WordTest.sort_transform(%w(foo bar baz quux))
# => "fbbq-bbfq-bbfq-bbfq"
# [].word doesn't work here
[].word
# => NoMethodError (undefined method `word' for []:Array)
Using each for object with an array of objects
In ruby we do chain methods to accomplish different complicated transforms:
@cars.map do |car|
[car.id, car.mileage]
end.each do |id, mileage|
...
end
Can I add object to an array in a loop and then return the array in the same line?
barcodes = Array.new(count){ Barcode.create }
Call method of an object in an array
So the problem is in your implementation of StockList
. You have extended the class array but are setting up a new instance variable @stockList
. When you call addStock
you are adding an instance to the @stockList
variable. But when you call each
on the StockList
instance, it is not iterating over the StockList
.
Conceivably, you could add a method each
to StockList
like:
def each(&block)
@stockList.each(&block)
end
and it should work.
But really I would recommend rethinking your data structures. StockList
should really not extend Array
.
Ruby Array Extension
Extending Array
means that you should be using self
rather than passing in an array. Right now, you're summing an empty array (from the default parameter) rather than the array that #sum
is called on.
Related Topics
Ruby Project Help. Can't Get Saved Instances from Array
Running Rake Task from Within War File
How to Install Version Specified Ruby Using Apt
When Joining Table, Rails Anyway Makes Additional Request When Accessing Fields from Joined Table
How to Count the Frequencies of the Letters in User Input
PDF Generation Hangs Using PDFkit and Wkhtmotopdf
How to Get Order Username and Provisiondate for All Softlayer MAChines Using Ruby
How to Convert Timestamp with Ruby
Why Must I Explicitly Call Self on Accessor When Using the Array Union Operator |= in Ruby
Implementing Dry-Run in Ruby Script
Why Sinatra Request Takes Em Thread
Rails - How to Add Contacts to Sendgrid Marketing Campaigns via API
Pageobject with Ruby - Set Text in a Text Field Only Works in the Main File