Reputation: 2121
Lets say that I have the class:
class Car
attr_accessor :brand, :color
def initialize(br, col)
@brand = br
@color = col
end
end
first_car = Car.new 'Mercedes', 'Yellow'
second_car = Car.new 'Jaguar', 'Orange'
third_car = Car.new 'Bentley', 'Pink'
array_of_cars = [first_car, second_car]
So, the idea is to define a method to_proc
in the class Array so this can happen:
array_of_cars.map(&[:brand, :color]) #=> [['Mercedes', 'Yellow'], ['Jaguar', 'Orange'], ['Bentley', 'Pink']]
or how could I somehow do something like this:
[:brand, :color].to_proc.call(first_car) #=> ['Mercedes', 'Yellow']
Upvotes: 1
Views: 179
Reputation: 205
Maybe use a normal method?
module ConvertInstanceToHash
def to_proc(obj, keys)
hash = {}
obj.instance_variables.each {|var| hash[var.to_s.delete("@")] = obj.instance_variable_get(var)}
hash = hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
hash.values_at(*keys).compact
end
end
irb(main):009:0> first_car = Car.new 'Mercedes', 'Yellow'
=> #<Car:0x000000045fb870 @brand="Mercedes", @color="Yellow">
irb(main):010:0> to_proc(first_car, [:brand, :color])
=> ["Mercedes", "Yellow"]
Upvotes: 0
Reputation: 3326
class Array
def to_proc(arr)
self.map do |elem|
arr.map { |attr| elem.send(attr) }
end
end
end
Like mu is too short
mentioned, I wouldn't patch Array
like this.
But, this will get the work done for you.
Invoke it as such:
array_of_cars.to_proc([:brand, :color])
Upvotes: 0
Reputation: 434685
The standard Symbol#to_proc
is, more or less, a e.send(self)
call and you just want to send
an array full of symbols to each element so just say exactly that with something like this:
class Array
def to_proc
proc { |e| self.map { |m| e.send(m) } }
end
end
I'd probably not patch Array for this, I'd just use a local lambda if I wanted something easier to read:
brand_and_color = lambda { |e| [:brand, :color].map { |s| e.send(s) } }
array_of_cars.map(&brand_and_color)
Upvotes: 5