ruby - &: syntax for methods with arguments -


i have nested array:

a = [[1, "aldous huxley"],      [3, "sinclair lewis"],      [2, "ernest hemingway"],      [4,"anthony burgess"]] 

a.collect { |author| author.drop(1) }

outputs

[["aldous huxley"], ["sinclair lewis"], ["ernest hemingway"], ["anthony burgess"]] 

while

a.collect(&:drop(1))

gives me sintax error.

syntaxerror: (irb):18: syntax error, unexpected '(', expecting ')' a.collect(&:drop(1))                   ^ 

is possible define original block expression in &: syntax?

the colon part of symbol in ruby, & magic makes syntax work, calling to_proc on object , using block. so, while can't use symbol :drop(1), can accomplish without using symbol in 2 ways:

1) return proc method , pass in:

def drop(count)   proc { |instance| instance.drop(count) } end a.collect(&drop(1)) 

2) pass in object responds to_proc:

class drop   def initialize(how_many = 1)     @to_drop = how_many   end    def to_proc     proc { |instance| instance.drop(@to_drop) }    end end drop = drop.new(1) a.collect(&drop) # or, more succinctly a.collect(&drop.new(1)) 

in simple case this, defining methods return procs or objects respond to_proc overkill , passing block collect better, there use cases it's not.


update: thinking more, symbol class doesn't have call method, doesn't mean can't:

module symbolcall   def call(*args)     proc { |instance| instance.public_send(self, *args) }   end end  class symbol   include symbolcall end  a.collect(&:drop.(1)) # or a.collect(&:drop.call(1)) 

just make sure don't forget it's method call :drop.(1) not :drop(1).


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -