`new`关键字如何在这个Ruby方法定义中工作?

dee*_*dee 9 ruby refactoring ruby-on-rails

Railscasts发布了一篇关于重构的精彩集.一种方法是将复杂的控制器逻辑移动到服务对象中,而不是将其推送到模型中.在一个服务对象中,使用以下代码:

class PasswordReset
  attr_reader :user

  def self.from_email(email)
    new User.find_by_email(email)
  end

  def self.from_token(token)
    new User.find_by_password_reset_token!(token)
  end
  ...
end
Run Code Online (Sandbox Code Playgroud)

new两个方法体中关键词的作用是什么?new User.find_by_.那有什么不同User.find_by_

这是调用代码:

  def create # controller
    password_reset = PasswordReset.from_email(params[:email])
    if password_reset.user
      password_reset.send_email
      redirect_to root_url, notice: "Email sent with password reset instructions."
    else
      redirect_to new_password_reset_url, alert: "Email address does not match a user account."
    end
  end
Run Code Online (Sandbox Code Playgroud)

还有,为什么attr_reader :user需要?

Jef*_*tte 11

classname隐含在self方法中.代码可以写成:

 def self.from_email(email)
    PasswordReset.new User.find_by_email(email)
 end
Run Code Online (Sandbox Code Playgroud)

要回答问题的后半部分,请attr_reader定义实例变量和读取器方法(如果您来自java或c#,则称为getter方法).把它们放在一起,你可以把它写成:

class PasswordReset


  def user
    @user
  end

  def self.from_email(email)
    PasswordReset.new User.find_by_email(email)
  end

  def self.from_token(token)
    PasswordReset.new User.find_by_password_reset_token!(token)
  end
  ...
end
Run Code Online (Sandbox Code Playgroud)

这假设PasswordReset#initialize将User作为参数,并相应地设置@user

  • 在代码审查中,我甚至认为使用简单的"新"是不直观的,并迫使任何人支持阅读整个方法,甚至是类,只是为了看看发生了什么.使用`PasswordReset.new`更加清晰和自我记录.甚至在括号中使用参数的`new(...)`也会有所改进,因此对于最初编写代码的人来说是-1,而对于建议更清晰/更清晰的解决方案来说是+1. (2认同)