Ruby if语句有问题';s逻辑

Ruby if语句有问题';s逻辑,ruby,Ruby,我有一种方法可以检查用户是否已完成其配置文件信息: def checkUser if (current_user.fullname.nil? && current_user.availability.nil? && current_user.rate.nil? && current_user.terms.nil? && current_user.location_city.nil? && current_user

我有一种方法可以检查用户是否已完成其配置文件信息:

def checkUser
  if (current_user.fullname.nil? && current_user.availability.nil? && current_user.rate.nil? && current_user.terms.nil? && current_user.location_city.nil? && current_user.location_state.nil? && current_user.location_country.nil? && current_user.biography.nil?)
    return true
  else
    return false
  end
end
当我尝试时,似乎有什么不对劲。速率属性为空(nil),全名属性不为空

我正在调试,发现
current\u user.rate.nil?
返回为
true
,而
current\u user.rate.nil?
返回为
false
,这是正常的。然而,通过使用Rails.logger.info,我发现checkUser方法返回的是
true
,而不是
false


我不确定我用来返回真或假的方式是否合适。if条件中的返回true或false是否表示checkUser方法的返回值?

空字符串与
nil
不同。如果用户没有输入任何内容,它可能只是空字符串,而不是nil

"".nil?
"".empty?

此外,只有当所有内容都为
nil
时,您的方法才会返回true。这似乎不是正确的逻辑。如果有任何字段没有填写,我假设您希望它返回true?

空字符串与
nil
不同。如果用户没有输入任何内容,它可能只是空字符串,而不是nil

"".nil?
"".empty?

此外,只有当所有内容都为
nil
时,您的方法才会返回true。这似乎不是正确的逻辑。我假设如果有任何字段没有填写,您希望它返回true?

关键字
return
将立即停止方法的执行,并返回传递给它的任何值。在这种情况下,为true或false。

return关键字将立即停止方法的执行,并返回传递给它的任何值。在这种情况下,是真是假。

思考一下:

def checkUser
  if (current_user.fullname.nil? && current_user.availability.nil? && current_user.rate.nil? && current_user.terms.nil? && current_user.location_city.nil? && current_user.location_state.nil? && current_user.location_country.nil? && current_user.biography.nil?)
    return true
  else
    return false
  end
end
可以这样写:

def valid?
  current_user.fullname.nil? && 
  current_user.availability.nil? && 
  current_user.rate.nil? && 
  current_user.terms.nil? && 
  current_user.location_city.nil? && 
  current_user.location_state.nil? && 
  current_user.location_country.nil? && 
  current_user.biography.nil?
end
可简化为:

def valid?
  [
    current_user.fullname, 
    current_user.availability, 
    current_user.rate, 
    current_user.terms, 
    current_user.location_city, 
    current_user.location_state, 
    current_user.location_country, 
    current_user.biography
  ].all?{ |v| v.nil? }
end
但这甚至可以归结为:

def valid?
  [
    :fullname, 
    :availability, 
    :rate, 
    :terms, 
    :location_city, 
    :location_state, 
    :location_country, 
    :biography
  ].all?{ |m| current_user.send(m).nil? }
end
需要考虑的事项:

  • 在方法中看到的最后一个值将由Ruby自动返回。这意味着如果比较已经返回真值或假值,则不必说
    返回真值
    返回假值
    。事实上,如果不需要的话,使用显式的
    返回一些_值
    ,这被认为是不好的Ruby风格,因为它浪费了打字、空间和阅读所必需的大脑能量
  • Ruby中的方法名是用snake_大小写的,而不是camelCase。在你读到一个很长的名字和你的大脑之前,它似乎是一件很小的事情
  • 当方法名是动词或提问时,读起来更好。“check_user”是可以的,但是将这样的方法称为“valid?”或“is_OK?”更为惯用,因为您需要一个布尔真/假响应
思考一下:

def checkUser
  if (current_user.fullname.nil? && current_user.availability.nil? && current_user.rate.nil? && current_user.terms.nil? && current_user.location_city.nil? && current_user.location_state.nil? && current_user.location_country.nil? && current_user.biography.nil?)
    return true
  else
    return false
  end
end
可以这样写:

def valid?
  current_user.fullname.nil? && 
  current_user.availability.nil? && 
  current_user.rate.nil? && 
  current_user.terms.nil? && 
  current_user.location_city.nil? && 
  current_user.location_state.nil? && 
  current_user.location_country.nil? && 
  current_user.biography.nil?
end
可简化为:

def valid?
  [
    current_user.fullname, 
    current_user.availability, 
    current_user.rate, 
    current_user.terms, 
    current_user.location_city, 
    current_user.location_state, 
    current_user.location_country, 
    current_user.biography
  ].all?{ |v| v.nil? }
end
但这甚至可以归结为:

def valid?
  [
    :fullname, 
    :availability, 
    :rate, 
    :terms, 
    :location_city, 
    :location_state, 
    :location_country, 
    :biography
  ].all?{ |m| current_user.send(m).nil? }
end
需要考虑的事项:

  • 在方法中看到的最后一个值将由Ruby自动返回。这意味着如果比较已经返回真值或假值,则不必说
    返回真值
    返回假值
    。事实上,如果不需要的话,使用显式的
    返回一些_值
    ,这被认为是不好的Ruby风格,因为它浪费了打字、空间和阅读所必需的大脑能量
  • Ruby中的方法名是用snake_大小写的,而不是camelCase。在你读到一个很长的名字和你的大脑之前,它似乎是一件很小的事情
  • 当方法名是动词或提问时,读起来更好。“check_user”是可以的,但是将这样的方法称为“valid?”或“is_OK?”更为惯用,因为您需要一个布尔真/假响应

    • 这里有很多改进的空间

      首先,放弃return关键字,因为它只是短路方法所必需的。例如

      def age_category
        return "unknown" if age.nil?
      
        if age < 0
          "unborn"
        elsif age < 18
          "child"
        elsif age < 65
          "adult"
        elsif age < 120
          "senior"
        else
          "ancient"
        end  
      end
      
      但是,选中的条件本身返回一个布尔值,因此不需要if/else。只需计算括号

      def checkUser
        (current_user.fullname.nil? && current_user.availability.nil? && current_user.rate.nil? && current_user.terms.nil? && current_user.location_city.nil? && current_user.location_state.nil? && current_user.location_country.nil? && current_user.biography.nil?)
      end
      
      然而,所有这些代码都不是面向对象的。为什么有一种方法可以对用户对象进行严格的检查,以确定它是否完整?用户对象应该能够告诉您这一点,以便您可以编写:

      def check_user
        current_user.complete?
      end
      
      在用户类上,可以实现以下方法

      def complete?
        [fullname, availability, rate, terms, location_city, location_state, location_country, biography].none? {|attribute| attribute.to_s.empty?}
      end
      

      此方法创建一个包含所有属性的数组。然后,它将它们转换为一个字符串,以检查它们是否为空。如果没有一个属性是空的,则该方法返回true。

      这里有很多改进的空间

      首先,放弃return关键字,因为它只是短路方法所必需的。例如

      def age_category
        return "unknown" if age.nil?
      
        if age < 0
          "unborn"
        elsif age < 18
          "child"
        elsif age < 65
          "adult"
        elsif age < 120
          "senior"
        else
          "ancient"
        end  
      end
      
      但是,选中的条件本身返回一个布尔值,因此不需要if/else。只需计算括号

      def checkUser
        (current_user.fullname.nil? && current_user.availability.nil? && current_user.rate.nil? && current_user.terms.nil? && current_user.location_city.nil? && current_user.location_state.nil? && current_user.location_country.nil? && current_user.biography.nil?)
      end
      
      然而,所有这些代码都不是面向对象的。为什么有一种方法可以对用户对象进行严格的检查,以确定它是否完整?用户对象应该能够告诉您这一点,以便您可以编写:

      def check_user
        current_user.complete?
      end
      
      在用户类上,可以实现以下方法

      def complete?
        [fullname, availability, rate, terms, location_city, location_state, location_country, biography].none? {|attribute| attribute.to_s.empty?}
      end
      

      此方法创建一个包含所有属性的数组。然后,它将它们转换为一个字符串,以检查它们是否为空。如果没有任何属性为空,该方法返回true。

      考虑读取条件分支如何工作。对于<代码> CurrutoSuff.Fr.nIL./COD>返回“<代码> true <代码> >是不正常的,如果它返回<代码> false …考虑阅读条件分支如何工作。如果代码返回,<代码> CurrnSuff.Fr.nIL.<代码>返回“<代码> true <代码> >是不正常的。
      false
      …在最后一个示例中,如果我使用| |而不是&&会怎么样?试试看
      | |
      &&
      不同,除非您对其进行一些令人费解的“非”更改,否则它不会起到替换的作用,这会使逻辑更难理解。我明白了。我所说的是您使用的最后一个示例“.all?”我假设它用于替换我使用的所有&&I。如果我使用| | ins怎么办