J'ai une application Rails avec quelque chose comme ceci:

[{name: 'joe'}, {name:'jane', sort: true, suppress: false}].map {|i| i.slice!(:sort, :suppress) }

Et aimerait utiliser quelque chose comme map(&:slice ... ) mais je ne sais pas si cela peut être fait. Je vois cette question Symbol # to_proc avec des méthodes personnalisées mais a 5 ans et je pense que cela doit être pris en charge en particulier dans Rails. Comment ferais-je cela?

En train de faire

[{name: 'joe'}, {name:'jane', sort: true, suppress: false}].map {|i| i.slice!(:sort, :suppress) }
0
ibpix 17 sept. 2020 à 20:01

2 réponses

Meilleure réponse

Autant que je sache, c'est le moyen le plus simple de le faire sans le patching de singe comme indiqué dans le lien que vous avez donné. Vous ne gagnez vraiment pas beaucoup de temps en utilisant un format plus compact. Si vous souhaitez le compacter davantage, vous pouvez déplacer la carte dans sa propre méthode. alors fais quelque chose comme

def map_slice!(arr, *fields)
  arr.map {|i| i.slice!(*fields) }
end

map_slice!(arr, :sort, :suppress)

# Not much shorter than just using below
# Which is why it probably wasn't implemented.
arr.map {|i| i.slice!(:sort, :suppress) }
2
Nuclearman 17 sept. 2020 à 19:16

Malheureusement, ce n'est pas possible sans le patching de singe. Quoi qu'il en soit, si vous avez un fort désir, vous pouvez patcher la classe Symbol.

class Symbol
  def with(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

Et ensuite vous pouvez l'utiliser comme:

[{name: 'joe'}, {name:'jane', sort: true, suppress: false}].map(&:slice.with(:name, :suppress))
1
m.seliverstov 17 sept. 2020 à 21:24