|
| 1 | +# Defined? |
| 2 | + |
| 3 | +In Ruby, the `defined?` keyword is a special operator that checks whether a given expression is defined and returns a description of that expression, or `nil` if the expression is not defined. |
| 4 | + |
| 5 | +```ruby |
| 6 | +# Basic defined? usage |
| 7 | +x = 42 |
| 8 | +puts defined?(x) # Output: local-variable |
| 9 | +puts defined?(y) # Output: nil |
| 10 | +puts defined?(puts) # Output: method |
| 11 | +``` |
| 12 | + |
| 13 | +The `defined?` operator can check various types of expressions and returns different description strings based on the type. |
| 14 | + |
| 15 | +```ruby |
| 16 | +# Checking different types |
| 17 | +class Example |
| 18 | + CONSTANT = "Hello" |
| 19 | + @@class_var = "World" |
| 20 | + |
| 21 | + def check_definitions |
| 22 | + @instance_var = "!" |
| 23 | + |
| 24 | + puts defined?(CONSTANT) # Output: constant |
| 25 | + puts defined?(@@class_var) # Output: class variable |
| 26 | + puts defined?(@instance_var) # Output: instance-variable |
| 27 | + puts defined?(yield) # Output: yield (if block given) |
| 28 | + puts defined?(super) # Output: super (if method has super) |
| 29 | + end |
| 30 | +end |
| 31 | + |
| 32 | +example = Example.new |
| 33 | +puts defined?(Example) # Output: constant |
| 34 | +puts defined?(String) # Output: constant |
| 35 | +puts defined?("string") # Output: expression |
| 36 | +``` |
| 37 | + |
| 38 | +## Common Use Cases |
| 39 | + |
| 40 | +The `defined?` operator is often used for safe navigation and checking existence before execution. |
| 41 | + |
| 42 | +```ruby |
| 43 | +def safe_operation(value) |
| 44 | + return "No block given" unless defined?(yield) |
| 45 | + |
| 46 | + if defined?(value.length) |
| 47 | + "Length is #{value.length}" |
| 48 | + else |
| 49 | + "Cannot determine length" |
| 50 | + end |
| 51 | +end |
| 52 | + |
| 53 | +puts safe_operation([1, 2, 3]) { |x| x * 2 } # Output: Length is 3 |
| 54 | +puts safe_operation(42) { |x| x * 2 } # Output: Cannot determine length |
| 55 | +puts safe_operation([1, 2, 3]) # Output: No block given |
| 56 | +``` |
| 57 | + |
| 58 | +## Method and Block Checking |
| 59 | + |
| 60 | +`defined?` is particularly useful for checking method existence and block presence. |
| 61 | + |
| 62 | +```ruby |
| 63 | +class SafeCaller |
| 64 | + def execute |
| 65 | + if defined?(before_execute) |
| 66 | + before_execute |
| 67 | + end |
| 68 | + |
| 69 | + puts "Executing main logic" |
| 70 | + |
| 71 | + if defined?(after_execute) |
| 72 | + after_execute |
| 73 | + end |
| 74 | + end |
| 75 | + |
| 76 | + def after_execute |
| 77 | + puts "After execution" |
| 78 | + end |
| 79 | +end |
| 80 | + |
| 81 | +caller = SafeCaller.new |
| 82 | +caller.execute |
| 83 | +# Output: |
| 84 | +# Executing main logic |
| 85 | +# After execution |
| 86 | + |
| 87 | +# Block checking |
| 88 | +def process_with_block |
| 89 | + if defined?(yield) |
| 90 | + "Block given: #{yield}" |
| 91 | + else |
| 92 | + "No block given" |
| 93 | + end |
| 94 | +end |
| 95 | + |
| 96 | +puts process_with_block { "Hello!" } # Output: Block given: Hello! |
| 97 | +puts process_with_block # Output: No block given |
| 98 | +``` |
| 99 | + |
| 100 | +The `defined?` operator is a powerful tool for writing defensive code and handling optional features or dependencies in Ruby programs. |
0 commit comments