not_nil에 Ruby 또는 Ruby-ism이 있습니까? nil의 반대? 방법?


87

나는 Ruby에 대한 경험이 없기 때문에 내 코드는 관용적이지 않고 "추악"하다고 느낀다.

def logged_in?
  !user.nil?
end

차라리

def logged_in?
  user.not_nil?
end

그러나 반대되는 방법을 찾을 수 없습니다. nil?

답변:


51

ActiveSupport를 사용할 때 user.present? http://api.rubyonrails.org/classes/Object.html#method-i-present%3F 가 있습니다. nil이 아닌지 확인하십시오.

def logged_in?
  user # or !!user if you really want boolean's
end

48
주의 : present?공백이 아닌 문자열이 필요합니다. ! "".nil?true를 "".present?반환 하지만 false를 반환합니다.
lambshaanxy 2011 년

9
주의 2 : 또한 !! 사용자는 사용자가 nil 인 것과 사용자가 거짓 인 것을 구별하지 않습니다. 더블 뱅 사용은이 둘을 합친다. 따라서 객체가 nil이 아닌지 (의미 : true, false, 0, "", nil이 아닌 다른 것) 진정으로 확인하고 싶다면 berkes가 싫어하는 '추악한'접근 방식을 사용해야합니다. 또는 @Tempus 가 아래에서 제안 하는 monkeypatch . 물론 nil이 필요 하지 않은 경우 (Rails의 사용자) Samo취하는 접근 방식 은 가장 못생긴 imo입니다.
likethesky

12
false.present? == false !false.nil? == true
Dudo 2014

3
이 대답은 질문에 전혀 대답하지 않습니다. 이 특정 구현 문제에 대한 답입니다.
Ekkstein 2016

3
이 대답은 정확하지 않습니다. false.nil? false 인 동안 false.present? 또한 거짓입니다!
Mike

49

부울에 지나치게 관심이있는 것 같습니다.

def logged_in?
  user
end

사용자가 nil이면 login_in? "거짓"값을 반환합니다. 그렇지 않으면 객체를 반환합니다. Ruby에서는 JavaScript처럼 "truthy"및 "falsey"값이 있으므로 true 또는 false를 반환 할 필요가 없습니다.

최신 정보

Rails를 사용하는 경우 다음 present?메소드 를 사용하여 더 잘 읽을 수 있습니다 .

def logged_in?
  user.present?
end

1
a로 끝나는 메서드의 예상 ?은 부울을 반환한다는 것입니다. !!value무엇이든 부울로 변환하는 고전적인 방법입니다. 정확히 동일하지는 않지만이 경우 Object#present?RoR도 좋습니다.
tokland

이것은 실제로 Ruby 2.4에서 Path를 사용하여 중단됩니다! [43] (pry) # <ReactOnRails :: AssetsPrecompile> : 0> assets_path.blank? true [44] (pry) # <ReactOnRails :: AssetsPrecompile> : 0> assets_path.to_s "/ var / folders / rp / _k99k0pn0rsb4d3lm9l3dnjh0000gn / T / d20170603-96466-zk7di7"[45] (pry) # <ReactOnRails :: AssetsPrecompile > : 0> assets_path.present? false [46] (pry) # <ReactOnRails :: AssetsPrecompile> : 0> assets_path.nil? 거짓
justingordon

25

질문에 대한 답변으로 제시 present?되는 다른 답변을 조심하십시오 .

present?blank?in rails 의 반대입니다 .

present?의미있는 값이 있는지 확인합니다. 다음은 present?검사에 실패 할 수 있습니다 .

"".present? # false
"    ".present? # false
[].present? # false
false.present? # false
YourActiveRecordModel.where("false = true").present? # false

반면 !nil?검사가 있습니다 :

!"".nil? # true
!"    ".nil? # true
![].nil? # true
!false.nil? # true
!YourActiveRecordModel.where("false = true").nil? # true

nil?개체가 실제로 있는지 확인합니다 nil. 다른 건 : 빈 문자열은 0, false무엇이든 아니다 nil.

present?매우 유용하지만 nil?. 두 가지를 혼동하면 예기치 않은 오류가 발생할 수 있습니다.

귀하의 사용 사례 present?는 작동하지만 항상 차이점을 인식하는 것이 좋습니다.


수락 된 답변에 포함되어야합니다. false.blank?다음과 같지 않습니다false.nil?
Yason

present?당신의 데이터베이스를 쿼리 할 nil?것입니다.주의 할 것입니다.
Tony

17

아마도 이것이 접근 방식 일 수 있습니다.

class Object
  def not_nil?
    !nil?
  end
end

좋은 생각. 나는 이것으로부터 not_nil이 없다고 만든다? 루비에서. 그러나 이것은 !self.nil?오히려 그럴 필요 가 없습니까 !nil?, 아니면 self암시 적입니까?
berkes

3
당신은 자기가 필요하지 않습니다. 암시 될 것입니다.
Geo

Self는 인스턴스 메서드 (또는 실제로 메서드 인 접근 자)에서 읽을 때 암시됩니다. 값을 설정할 때 Ruby가 클래스 인스턴스에서 동일한 이름의 setter 메서드를 확인하기 전에 메서드에 로컬 변수가 생성됩니다. 일반 규칙 : xxx라는 attr_accessor가있는 경우 "self.xxx = 3"(값 설정) 또는 "temp = xxx"(값 읽기)를 사용하십시오. "xxx = 3"을 사용하면 접근자를 업데이트하지 않고 메서드 범위에 새 변수를 만듭니다.
페이더 어둡

4

다음을 사용할 수 있습니다.

if object
  p "object exists"
else
  p "object does not exist"
end

이것은 nil뿐만 아니라 false 등에서도 작동하므로 사용 사례에서 작동하는지 테스트해야합니다.


4

!방법의 결과에 대해 Ruby-esque 방법을 제공 할 수 있습니다 nil?.

def logged_in?
  user.nil?.!
end

RubyMine IDE가 오류로 플래그를 표시 할 정도로 난해합니다. ;-)


2

나는 블록 대신 Symbol#to_proc속기 를 사용할 수 있도록 객체 메서드를 찾고이 질문에 도달했습니다 . 내가 찾아 arr.find(&:not_nil?)보다 다소 더 읽기 arr.find { |e| !e.nil? }.

내가 찾은 방법은 Object#itself. 내 사용법에서 키에 대한 해시 값을 찾고 싶었 name습니다. 어떤 경우에는 키가 실수로 Name. 그 한 줄짜리는 다음과 같습니다.

# Extract values for several possible keys 
#   and find the first non-nil one
["Name", "name"].map { |k| my_hash[k] }.find(&:itself)

다른 답변 에서 언급했듯이 부울을 테스트하는 경우 이것은 크게 실패합니다.


그게 어떻게 my_hash.values_at("Name", "name").find다릅니 까?

똑같습니다. map이 예제에서는 간단하게 제거한 원본에 다른 논리가 있었 으므로 여기에 작성된대로 values_at. 중요한 부분은 전달되는 것 find입니다.
Ian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.