L'essentiel est que vous ne devriez pas faire un retour anticipé lorsque vous prenez des notes en Ruby (probablement pas seulement en Ruby).
def user
@user ||= begin
user = User.find_or_initialize_by(id: 1)
return user if user.persisted? #Ne pas retourner lors de la définition des variables d'instance
user.save
user
end
end
def user
@user ||= begin
user = User.find_or_initialize_by(id: 1)
if user.persisted?
user
else
user.save
user
end
end
end
#Ou
def user
@user ||= begin
user = User.find_or_initialize_by(id: 1)
user.save if user.new_record?
user
end
end
Lorsque vous utilisez des mémos dans Ruby (Rails), vous pouvez écrire quelque chose comme ce qui suit.
def user
@user ||= User.first
end
S'il y a plusieurs lignes, placez-les entre begin
~ ʻend`.
def user
@user ||= begin
user = user.find_or_initialize_by(id: 1)
if user.persisted?
user
else
user.save
user
end
end
end
Utilisons le retour anticipé, qui est une technique de refactoring courante.
def user
@user ||= begin
user = User.find_or_initialize_by(id: 1)
return user if user.persisted?
user.save
user
end
end
À première vue, ça a l'air bien, mais quand j'exécute cette méthode sur la console des rails, ça ressemble à ceci:
[1] pry(main)> def user
[1] pry(main)* @user ||= begin
[1] pry(main)* user = User.find_or_initialize_by(id: 1)
[1] pry(main)* return user if user.persisted?
[1] pry(main)*
[1] pry(main)* user.save
[1] pry(main)* user
[1] pry(main)* end
[1] pry(main)* end
=> :user
[2] pry(main)> user
User Load (3.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User:0x00007ff0b4d2e338
id: 1,
created_at: Tue, 09 Jun 2020 15:04:04 JST +09:00,
updated_at: Tue, 09 Jun 2020 15:04:04 JST +09:00>
[3] pry(main)> user
User Load (1.8ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User:0x00007ff0ad554740
id: 1,
created_at: Tue, 09 Jun 2020 15:04:04 JST +09:00,
updated_at: Tue, 09 Jun 2020 15:04:04 JST +09:00>
Aucun mémo n'est fait et une requête est émise à chaque fois. Si vous vérifiez à nouveau la référence,
Manuel de référence Ruby 2.7.0 https://docs.ruby-lang.org/ja/latest/doc/spec=2fcontrol.html#return return Termine l'exécution de la méthode avec la valeur de l'expression comme valeur de retour.
Puisqu'il y a une instruction, la méthode ʻuser se termine au stade de
return, et la variable d'instance de
@ user reste
nil`, donc le processus est exécuté à chaque fois.
C'est naturel quand vous y réfléchissez, mais soyez prudent car vous pouvez devenir accro à l'écriture que vous utilisez souvent des retours anticipés dans votre habitude.
Recommended Posts