ruby.onl / hidden-gems

Predicate Methods: The ? That Answers Yes or No

2026-03-22

Ruby methods ending in ? return true or false. They're Ruby's convention for "ask a question" methods. Perl has no equivalent naming convention, but the functionality maps to various Perl checks. The difference is that in Ruby, you can read the code like English.

Part 1: Collection Predicates

# any? - true if ANY element matches lines.any?(&:empty?) # any empty lines? lines.any? { |l| l.size > 80 } # any long lines? lines.any?(%r~^#~) # any comments? (regex form) # all? - true if ALL elements match lines.all? { |l| l.size < 80 } # all lines short? nums.all?(&:positive?) # all positive? # none? - true if NO elements match lines.none?(&:empty?) # no empty lines? lines.none?(%r~^#~) # no comments? # one? - true if EXACTLY ONE matches lines.one?(%r~^BEGIN~) # exactly one BEGIN line? # empty? - true if collection has no elements [].empty? # => true "".empty? # => true (works on strings too!)

Part 2: String Predicates

# include? - substring check "hello world".include?("world") # => true # Perl: index($str, "world") != -1 # start_with? - prefix check "http://example.com".start_with?("http") # => true # Perl: $str =~ /^http/ # end_with? - suffix check "access.log".end_with?(".log") # => true # Perl: $str =~ /\.log$/ # match? - regex check (returns true/false, no captures) "hello123".match?(%r~\d+~) # => true # Faster than =~ when you don't need capture groups

Part 3: Numeric Predicates

42.positive? # => true -5.negative? # => true 0.zero? # => true 4.even? # => true 3.odd? # => true (5.0).infinite? # => nil (1.0/0).infinite? # => 1 (0.0/0).nan? # => true 42.between?(1, 100) # => true
Every number knows what it is. No more $n % 2 == 0 when you can just say n.even?.

Part 4: Hash Predicates

hash.key?(:foo) # key exists? hash.value?(42) # value exists? hash.empty? # no key-value pairs? # Perl equivalents: # exists $hash{foo} # grep { $_ == 42 } values %hash

Part 5: Nil and File Checks

# Nil check nil.nil? # => true "hello".nil? # => false 0.nil? # => false (0 is NOT nil in Ruby!) # Perl: !defined($var) # File predicates File.exist?("/etc/passwd") # file exists? File.file?("/etc/passwd") # is a regular file? File.directory?("/tmp") # is a directory? File.readable?("/etc/passwd") # readable by current user? File.writable?("/tmp/test") # writable? File.executable?("/usr/bin/ruby") # executable? File.empty?("/var/log/empty.log") # zero bytes? File.symlink?("/usr/local/bin/ruby") # symbolic link? # Perl: -e, -f, -d, -r, -w, -x, -z, -l file test operators
Perl's file tests are shorter (-e $file), but Ruby's are self-documenting. You never need to look up what -z means.

Part 6: Practical One-Liners

# Print non-empty lines ruby -ne 'puts $_ unless $_.chomp.empty?' # Print lines containing digits ruby -ne 'puts $_ if $_.match?(%r~\d~)' # Print lines that start with a letter ruby -ne 'puts $_ if $_.start_with?(*("a".."z").to_a, *("A".."Z").to_a)'

Part 7: Why ? Methods Matter

The ? suffix is just a naming convention (not enforced by Ruby), but it's used consistently across the standard library. When you see ? at the end of a method name, you know it returns a boolean. This makes code very readable compared to Perl where you'd need to check the return value context.

Created By: Wildcard Wizard. Copyright 2026