Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
puts "\nWays of creating a basic block:"

def pass_me_a_block_please
  yield
end

pass_me_a_block_please {
  puts "* Put it in brackets."
}

pass_me_a_block_please { puts "* In curly brackets, all on one line!" }

pass_me_a_block_please do
  puts "* Ooh. You're using 'do' to create a block."
end

puts "\nWhat happens if you don't pass a block?"

begin
  pass_me_a_block_please
rescue LocalJumpError
  puts "* Oops! Calling yield without passing a block raises a LocalJumpError"
end

puts "\nYou can use block_given? to test if a block has been passed."

def pass_me_a_block_if_you_want_to
  if block_given?
    puts "* If you can read this, you DID pass a block, and it's about to be evaluated:"
    yield
  else
    puts "* If you can read this, you didn't pass in a block."
  end
end

puts "About to not pass a block!"
pass_me_a_block_if_you_want_to # This is okay

puts "About to pass a block!"
pass_me_a_block_if_you_want_to { # So is this!
  puts "* If you can read this, the block you just passed has been evaluated!"
}

puts "\nYou can also just rescue the error if you don't pass in a block:"

def pass_me_a_block_if_you_want_to
  begin
    yield
  rescue LocalJumpError
    puts "* You didn't pass a block, but at least you rescued the error."
  end
end

pass_me_a_block_if_you_want_to

puts "\nLet's write a method with arguments AND a block!"

def pass_me_some_args(arg1, arg2)
  puts arg1
  puts arg2
  yield
end

pass_me_some_args("one", "two") {
  puts "three"
}

puts "\nAn ampersand before the last method argument means it's a block."

def pass_me_some_args_with_named_block_arg(arg1, arg2, &arg3)
  puts "\npass_me_some_args_with_named_block_arg"
  puts arg1
  puts arg2
  if arg3 # You can also test for a block like this if you have named it.
    puts "You passed a block named arg3 which is about to be evaluated:"
    yield
  else
    puts "No block passed."
  end
end

pass_me_some_args_with_named_block_arg("one", "two")

pass_me_some_args_with_named_block_arg("one", "two") {
  puts "three"
}

puts "\nWhat about variable scope?"

i_am_a_variable_already_defined = "defined_before_the_block_is_called"
pass_me_a_block_please {
  i_am_a_variable_already_defined = "i_can_be_changed_within_a_block"
}

puts "i_am_a_variable_already_defined: #{i_am_a_variable_already_defined}"

pass_me_a_block_please {
  i_am_just_a_local_variable = "the_answer_to_life_the_universe_and_everything"
}

begin
  puts "i_am_just_a_local_variable: #{i_am_just_a_local_variable}"
rescue NameError
  puts "we'll never know what was in i_am_just_a_local_variable"
end

def change_variable_in_the_method
  i_am_a_variable_local_to_this_method = "you_cant_change_me_in_the_block_about_to_be_called"
  yield
  puts "i_am_a_variable_local_to_this_method: #{i_am_a_variable_local_to_this_method}"
end

change_variable_in_the_method {
  i_am_a_variable_local_to_this_method = "this won't change anything!!"
}

begin
  puts "i_am_a_variable_local_to_this_method: #{i_am_a_variable_local_to_this_method}"
rescue NameError
  puts "I told you it was just local to that method!"
end