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 |
# This code is buggy and needs several test cases to assert the bugs are fixed. r = Relationship r = user1 r = user2 r = type code = 0 if !["friend", "spouse"] type type = "undefined" # BUG! We meant to write `r.type = "unknown"`. We are completely reliant on tests to catch it. code = 1 end r r_other = Relationship(...) logger "Interesting new relationship!" if r = r_other # BUG! We meant to write `r == r_other`. A test probably won't catch this. return code end # This code requires fewer tests, but is more verbose. # These parameter reference are immutable. final r = Relationship # This local variable is immutable as well. r = user1 r = user2 code = 0 # A normal Ruby variable. if !["friend", "spouse"] type type = "undefined" # RUNTIME ERROR! The runtime knows an error exists because we explicitly declared the parameter reference final code = 1 end r final r_other = Relationship(...) logger "Interesting new relationship!" if r = r_other # RUNTIME ERROR! We cannot make the assignment since the `r` reference is immutable. return code end # This best of both worlds. Requires fewer tests while still easy to understand. # All references are implicitly immutable unless declared otherwise. r = Relationship # The reference to `r` is immutable. r = user1 r = user2 r = type var code = 0 # Must be explicitly declared mutable since we are planning to change it. if !["friend", "spouse"] type type = "undefined" # RUNTIME ERROR! We meant to write `r.type = "unknown"`, but the runtime caught it since the `type` reference is immutable. No need to add a test case! code = 1 # Works fine since the variable was declared mutable. end r r_other = Relationship(...) logger "Interesting new relationship!" if r = r_other # RUNTIME ERROR! We meant to write `r == r_other`, but the runtime caught it since the `r` reference is immutable. return code end end |

