Question

J'ai deux exemples qui donnent le même résultat.

avec bloc:

def self.do_something(object_id)
  self.with_params(object_id) do |params|
    some_stuff(params)
  end
end

def self.with_params(object_id, &block)
  find_object_by_id
  calculate_params_hash
  block.call(params_hash)
end

et avec la méthode:

def self.do_something(object_id)
  some_stuff(self.get_params(object_id))
end

def self.get_params(object_id)
  find_object_by_id
  calculate_params_hash
  params_hash
end

La deuxième solution semble plus simple, mais j'ai trouvé des usages de la première dans notre code d'application.Ma question est la suivante: dans quelle situation le premier est recommandé?Quels sont les avantages et les inconvénients de chacun?

Était-ce utile?

La solution

La principale différence entre un bloc et une fonction selon votre exemple est que le bloc fonctionne dans le contexte de la fonction d'appel .

Donc, si votre exemple était comme:

def self.do_something(object_id)
  x = "boogy on"
  self.with_params(object_id) do |params|
    some_stuff(params)
    puts x
  end
end

Le code dans le bloc peut accéder à la variable X qui a été défini à l'extérieur du bloc. Ceci s'appelle une fermeture. Vous ne pouviez pas faire cela si vous appeliez simplement une fonction selon votre deuxième exemple.

Une autre chose intéressante sur les blocs est qu'elles peuvent affecter le flux de contrôle de la fonction extérieure. Il est donc possible de faire:

def self.do_something(object_id)
  self.with_params(object_id) do |params|
    if some_stuff(params)
        return
    end
  end

  # This wont get printed if some_stuff returns true.
  puts "porkleworkle"
end

Si l'appel quelque_stuff dans le bloc renvoie une valeur réelle, le bloc reviendra. Cela reviendra hors du bloc et hors de la méthode dossée . Porkleworkle n'obtiendrait pas la sortie.

Dans vos exemples, vous ne vous appuyez pas de l'une ou l'autre d'entre eux, il est donc probable que les appels de fonction sont probablement beaucoup plus propres.

Cependant, de nombreuses situations sont de nombreuses situations où utiliser des blocs pour vous permettre de profiter de ces choses sont inestimables.

Autres conseils

Normalement, les gens utilisent des blocs lorsqu'ils veulent exécuter un morceau de code à l'intérieur d'un autre morceau de code.Exemples:

DB.with_shard_for_user(user_id) do |db|
  # perform operations on a user's shard

end # shard is reverted back to original value

File.new(filename) do |file|
  # work with file
end # file is closed automatically

User.transaction do
  # run some operations as a single transaction
end

Ces blocs sont fermés sur leur contexte lexical (ils capturent des variables de l'endroit où le bloc est déclaré et les transporter à la place lorsque des blocs sont appelés).

Structure schématique d'une méthode qui accepte un bloc.

def transaction
  open_transaction # pre- part

  yield if block_given? # run provided code

  commit_transaction # post- part
rescue
  rollback_transaction # handle problems
end

Dans votre premier exemple, l'utilisation d'un bloc est probablement injustifiée (IMHO).Trop complexe sans raison apparente.

Lorsque vous appelez avec_params (), vous envoyez non seulement des données, vous fournissez également du code à exécuter.Voir si différents blocs sont envoyés dans l'appel avec_Params ():

...
self.with_params(object_id) do |params|
  some_other_stuff()
  some_stuff(params)
end
...

et ailleurs:

...
self.with_params(object_id) do |params|
  even_more_stuff(params)
end
...

Si les blocs sont tous identiques ou avec_params () est simplement appelé à partir d'un endroit, vous pourriez envisager d'éliminer les blocs.

Pour résumer: Utilisez des blocs si vous souhaitez passer à la méthode Différents bits de code (blocs) ainsi que des données: Hey with_params, prenez ces données (Object_id) et, à la manière, exécutez ce code (bloc)Pendant que vous êtes à cela.

BTW Vous faites différentes choses dans les deux exemples: avec_params () renvoie

some_stuff(params_hash)

Après avoir évalué le bloc.Et get_params () vient de retourner

params_hash

Un bloc comptez totalement sur votre code, mais une fonction a son propre code.

Donc, si votre code varie en situation de situation, utilisez le bloc. Sinon, construisez une fonction et utilisez-la comme boîte à blocs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top