Ruby 'return' 一个方法来自另一个方法?
Ruby 'return' a method from another method?
在一个Rails项目中,由于一些历史原因,Tiger
和Elephant
中的一段代码相同。
我不喜欢重复,但如果我在 AnimalController
class 中创建一个新方法并将这些代码移入其中,我就无法 return
[=来自新方法的 17=] 或 running
方法。
我认为 return 从另一种方法可能不是一个好的做法,但我真的很讨厌重复,有人可以帮我重构吗?
class AnimalController
# I want create a new method here
#def all_in
#end
end
class TigerController < AnimalController
def running # This is an Action
some_different_codes...
if arm.blank?
render_not_found
return # <- how can I return `running` from the new method?
end
if lag.nil?
invalid_id
return # <-
end
some_different_codes...
end
end
class ElephantController < AnimalController
def walk # This is an Action
some_different_codes...
if arm.blank?
render_not_found
return
end
if lag.nil?
invalid_id
return
end
some_different_codes...
end
end
一个方法不能让其调用者 return,如果它不想的话。所以这个新方法将执行检查(同时渲染一些东西)并且它将 return 检查结果。调用方方法分析 return 值并决定要做什么。沿着这些线的东西:
class AnimalController
def all_in
if invalid_id
render_not_found
return false
end
if lag.nil?
invalid_id
return false
end
true
end
end
class TigerController < AnimalController
def running # This is an Action
some_different_codes...
return unless all_in
some_different_codes...
end
end
可能是查找有关 callbacks and superclassing:
的好机会
回调 基本上允许您运行 根据另一个函数的响应在代码中登录。
由于我们到处都有他们 Rails,所以真正欣赏他们所做的事情的人并不多。如果你曾经用 JS 实现过它们,你就会了解它们!
-
Superclassing 是您从现有 class 继承的地方 - 允许您使用(和扩展)[=70= 的功能] 已。这就是 super 命令的来源。
我会这样做(看起来确实像Sergio
的回答,令人放心):
#app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
private
def all_in?
if invalid_id
return false
end
if lag.nil?
invalid_id
return false
end
true #-> ruby automatically returns the last line
end
end
以上是您所谓的 回调——您将能够调用 all_in
(在一个实例中)并收到 response
true
或 false
。
这将使您能够调用该方法(如果您是 superclassing
,该方法将在链下可用:
#app/controllers/elephants_controller.rb
class ElephantController < AnimalController
def walk # This is an Action
some_different_codes...
if all_in?
some_different_codes...
end
end
end
现在,有件事你必须知道。
这种类型的行为应该不放在您应用的控制器中——它应该放在您的中型号:
#app/models/animal.rb
class Animal < ActiveRecord::Base
def walk
end
end
#app/models/animals/elephant.rb
class Elephant < Animal
def walk
super ...
end
end
#app/models/animals/tiger.rb
class Tiger < Animal
end
以上称为STI (Single Table Inheritance)。它基本上是一种使用其他 "dependent" 模型及其方法对主模型进行子class 的方法。
由于 ruby 是 object orientated,您应该在对象本身上调用特定于对象的方法;
#config/routes.rb
resources :tigers, :elephants, controller: :animals
#url.com/tigers/
#url.com/elephants/
#app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
def show
@tiger = Tiger.find params[:id]
@tiger.walk
end
end
这或多或少体现在 state machine
:
class Vehicle
attr_accessor :seatbelt_on, :time_used, :auto_shop_busy
state_machine :state, :initial => :parked do
before_transition :parked => any - :parked, :do => :put_on_seatbelt
after_transition :on => :crash, :do => :tow
after_transition :on => :repair, :do => :fix
after_transition any => :parked do |vehicle, transition|
vehicle.seatbelt_on = false
end
...
在一个Rails项目中,由于一些历史原因,Tiger
和Elephant
中的一段代码相同。
我不喜欢重复,但如果我在 AnimalController
class 中创建一个新方法并将这些代码移入其中,我就无法 return
[=来自新方法的 17=] 或 running
方法。
我认为 return 从另一种方法可能不是一个好的做法,但我真的很讨厌重复,有人可以帮我重构吗?
class AnimalController
# I want create a new method here
#def all_in
#end
end
class TigerController < AnimalController
def running # This is an Action
some_different_codes...
if arm.blank?
render_not_found
return # <- how can I return `running` from the new method?
end
if lag.nil?
invalid_id
return # <-
end
some_different_codes...
end
end
class ElephantController < AnimalController
def walk # This is an Action
some_different_codes...
if arm.blank?
render_not_found
return
end
if lag.nil?
invalid_id
return
end
some_different_codes...
end
end
一个方法不能让其调用者 return,如果它不想的话。所以这个新方法将执行检查(同时渲染一些东西)并且它将 return 检查结果。调用方方法分析 return 值并决定要做什么。沿着这些线的东西:
class AnimalController
def all_in
if invalid_id
render_not_found
return false
end
if lag.nil?
invalid_id
return false
end
true
end
end
class TigerController < AnimalController
def running # This is an Action
some_different_codes...
return unless all_in
some_different_codes...
end
end
可能是查找有关 callbacks and superclassing:
的好机会回调 基本上允许您运行 根据另一个函数的响应在代码中登录。
由于我们到处都有他们 Rails,所以真正欣赏他们所做的事情的人并不多。如果你曾经用 JS 实现过它们,你就会了解它们!
-
Superclassing 是您从现有 class 继承的地方 - 允许您使用(和扩展)[=70= 的功能] 已。这就是 super 命令的来源。
我会这样做(看起来确实像Sergio
的回答,令人放心):
#app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
private
def all_in?
if invalid_id
return false
end
if lag.nil?
invalid_id
return false
end
true #-> ruby automatically returns the last line
end
end
以上是您所谓的 回调——您将能够调用 all_in
(在一个实例中)并收到 response
true
或 false
。
这将使您能够调用该方法(如果您是 superclassing
,该方法将在链下可用:
#app/controllers/elephants_controller.rb
class ElephantController < AnimalController
def walk # This is an Action
some_different_codes...
if all_in?
some_different_codes...
end
end
end
现在,有件事你必须知道。
这种类型的行为应该不放在您应用的控制器中——它应该放在您的中型号:
#app/models/animal.rb
class Animal < ActiveRecord::Base
def walk
end
end
#app/models/animals/elephant.rb
class Elephant < Animal
def walk
super ...
end
end
#app/models/animals/tiger.rb
class Tiger < Animal
end
以上称为STI (Single Table Inheritance)。它基本上是一种使用其他 "dependent" 模型及其方法对主模型进行子class 的方法。
由于 ruby 是 object orientated,您应该在对象本身上调用特定于对象的方法;
#config/routes.rb
resources :tigers, :elephants, controller: :animals
#url.com/tigers/
#url.com/elephants/
#app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
def show
@tiger = Tiger.find params[:id]
@tiger.walk
end
end
这或多或少体现在 state machine
:
class Vehicle
attr_accessor :seatbelt_on, :time_used, :auto_shop_busy
state_machine :state, :initial => :parked do
before_transition :parked => any - :parked, :do => :put_on_seatbelt
after_transition :on => :crash, :do => :tow
after_transition :on => :repair, :do => :fix
after_transition any => :parked do |vehicle, transition|
vehicle.seatbelt_on = false
end
...