JoshCheek / seeing_is_believing

Displays the results of every line of code in your file
1.31k stars 54 forks source link

Your shit blows up! #10

Closed NCCastillo closed 11 years ago

NCCastillo commented 11 years ago

It blew up because SeeingIsBelieving isn't good enough >.< Please log an issue at: https://github.com/JoshCheek/seeing_is_believing/issues

Program: "begin;($seeing_is_believing_current_result.record_result(9, (def destroy_message(string)\n($seeing_is_believing_current_result.record_result(2, ( matched_string = string.match(/:/))))\n($seeing_is_believing_current_result.record_result(7, ( if matched_string \n($seeing_is_believing_current_result.record_result(4, ( \"#{matched_string.pre_match}#{matchedstring}\")))\n else\n return \"this has no message\"\n end)))\n #string[/\A[^:]:/]\nend)))\n\n($seeing_is_believing_current_result.record_result(14, (def destroy_message!(string)\n # matched_string = string.match(/:/)\n($seeing_is_believing_current_result.recordresult(13, ( string.sub!(/(?<=:)./,''))))\nend)))\n\n# Driver code... \n($seeing_is_believing_current_result.record_result(17, (string = \"this message will self-destruct: you can't hug every cat\")))\n($seeing_is_believing_current_result.record_result(18, (original_string = string.dup)))\n($seeing_is_believing_current_result.record_result(19, (puts destroy_message(string) == \"this message will self-destruct:\")))\nputs string == original_string # we shouldn't modify the string passed to destroy_message\n\n($seeing_is_believing_current_result.record_result(22, (string = \"this has no message\")))\n($seeing_is_believing_current_result.record_result(23, (original_string = string.dup)))\n($seeing_is_believing_current_result.record_result(24, (puts destroy_message(string) == string)))\nputs string == original_string # we shouldn't modify the string passed to destroy_message\n\n($seeing_is_believing_current_result.record_result(27, (string = \"this message will self-destruct: you can't hug every cat\")))\n($seeing_is_believing_current_result.record_result(28, (original_string = string.dup)))\n($seeing_is_believing_current_result.record_result(29, (puts destroy_message!(string) == \"this message will self-destruct:\")))\n($seeing_is_believing_current_result.record_result(30, (puts string == \"this message will self-destruct:\")))\n($seeing_is_believing_current_result.record_result(31, (puts string != original_string)))\n\n($seeing_is_believing_current_result.record_result(33, (string = \"this has no message\")))\n($seeing_is_believing_current_result.record_result(34, (result = destroy_message!(string))))\n($seeing_is_believing_current_result.record_result(35, (puts result.nil?)))\n($seeing_is_believing_current_result.record_result(36, (puts string == string)))\n\nrescue Exception;line_number = $!.backtrace.grep(/#{FILE}/).first[/:\d+/][1..-1].to_i;$seeing_is_believing_current_result.record_exception line_number, $!;end"


Code that generated this:

def destroy_message(string)
  matched_string = string.match(/:/)              # => #<MatchData ":">, nil
  if matched_string 
  "#{matched_string.pre_match}#{matched_string}"  # => "this message will self-destruct:"
  else
    return "this has no message"                    # => nil
  end                                             # => "this message will self-destruct:", nil
  #string[/\A[^:]*:/]
end                                               # => nil

def destroy_message!(string)
 # matched_string = string.match(/:/)
  string.sub!(/(?<=:).*/,'')  # => "this message will self-destruct:", nil
end                           # => nil

# Driver code... 
string = "this message will self-destruct: you can't hug every cat"  # => "this message will self-destruct: you can't hug every cat"
original_string = string.dup                                         # => "this message will self-destruct: you can't hug every cat"
puts destroy_message(string) == "this message will self-destruct:"   # => nil
puts string == original_string # we shouldn't modify the string passed to destroy_message

string = "this has no message"          # => "this has no message"
original_string = string.dup            # => "this has no message"
puts destroy_message(string) == string  # => nil
puts string == original_string # we shouldn't modify the string passed to destroy_message

string = "this message will self-destruct: you can't hug every cat"  # => "this message will self-destruct: you can't hug every cat"
original_string = string.dup                                         # => "this message will self-destruct: you can't hug every cat"
puts destroy_message!(string) == "this message will self-destruct:"  # => nil
puts string == "this message will self-destruct:"                    # => nil
puts string != original_string                                       # => nil

string = "this has no message"     # => "this has no message"
result = destroy_message!(string)  # => nil
puts result.nil?                   # => nil
puts string == string              # => nil

# >> true
# >> true
# >> This has no message
# >> false
# >> true
# >> true
# >> true
# >> true
# >> true
# >> true
JoshCheek commented 11 years ago

Here is a simplified example of this error:

1.times do
  if true
    break
  end
end

It blows up b/c of a void value expression. E.g. same reason this blows up when run in normal Ruby:

1.times do
  puts(if true
    break
  end)
end

I don't know how to fix this without either making the regex super duper overly hyper conservative, or actually parsing Ruby for real. I'd prefer the latter, but it's beyond me at the moment, so this probably won't be fixed for a while :(

JoshCheek commented 11 years ago

Should be fixed with 259a6f98ce832986dc0f717ede26d65259d5c633 I'll close this once I understand @whitequark's comment so that I can feel confident this hits all the cases of void value expressions.