Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutation bug: "Can't change the value of self" #64

Closed
dkubb opened this issue Jul 12, 2013 · 10 comments
Closed

Mutation bug: "Can't change the value of self" #64

dkubb opened this issue Jul 12, 2013 · 10 comments

Comments

@dkubb
Copy link
Collaborator

dkubb commented Jul 12, 2013

I just found a bug in how mutant mutates expressions like: self.attr ||= something, eg:

/Users/dkubb/.rvm/gems/ruby-2.0.0-p247@jettstream-api/gems/mutant-0.3.0.beta13/lib/mutant/loader.rb:43:in `eval': /Users/dkubb/Dropbox/Home/Programming/work/jettstream/api/app/models/child/questionnaire/answer.rb:37: Can't change the value of self (SyntaxError)
          self ||= option.questionnaire_id
                  ^
evil:Child::Questionnaire::Answer#set_default_questionnaire_id:/Users/dkubb/Dropbox/Home/Programming/work/jettstream/api/app/models/child/questionnaire/answer.rb:32:bce57
@@ -1,6 +1,6 @@
 def set_default_questionnaire_id
   if option
-    self.questionnaire_id ||= option.questionnaire_id
+    self ||= option.questionnaire_id
   end
 end
@mbj
Copy link
Owner

mbj commented Jul 12, 2013

@dkubb Yeah, good catch an easy to fix. Will address it soon.

Interesting this one wasnt found more early. Most likely the amount of useing the op-assign operators was reduced a lot with dm2-rom-style.

@mbj
Copy link
Owner

mbj commented Jul 12, 2013

@dkubb While generalizing this kind of error I think I should also exclude cases with literal lhs!

@dkubb
Copy link
Collaborator Author

dkubb commented Jul 12, 2013

@mbj yeah, that's a good idea. Are there notes that represent literal values and includes things like: 'string', 1, nil, true, false etc?

At first I was thinking you should only include nodes known to support assignment; but then I realized you could easily accidentally miss whole classes of nodes with that approach. I guess using an explicit exclude approach is better. While it might take some tweaking to get the list complete, mutating everything by default is probably a better approach.

@mbj
Copy link
Owner

mbj commented Jul 12, 2013

@dkubb Jo, I'd only do blacklisting here. And yes identifying literals is easy just use Node#type.

:sym,:int,:nil,:true,:false,:self etc will be included.

@mbj
Copy link
Owner

mbj commented Jul 12, 2013

Also detection of that case is easy. The "inner" nodes mutator, the mutator that mutates the "self.attribute" has to detect it is within an op assign parent. And it will NOT invoke the "emit receiver" mutation if the receiver is of that type list I gave above.

I really love mutants design here. We have access to the parent mutator and can easily branch on the parents Node#type.

Mutant is a recursive tree walker emitting mutations and tracking context.

@dkubb
Copy link
Collaborator Author

dkubb commented Jul 12, 2013

It would be kind of weird for the receiver to be one of those nodes listed, besides self of course, but I suppose it could happen if you were to do something like:

class String
  attr_accessor :extra
end

# will blow up when mutated to: '' = 42
''.extra = 42

Even though I would consider this a bit dumb, it is valid ruby.

@mbj
Copy link
Owner

mbj commented Jul 12, 2013

@dkubb Do not confuse assignment with op-assign. = vs ||=.

@mbj
Copy link
Owner

mbj commented Jul 12, 2013

My pref comment is not valid.

@dkubb My english limits me here, let the code that fixes the problem speek. Soon, still busy with other stuff.

@mbj mbj closed this as completed in 4a2d12e Jul 14, 2013
@dkubb
Copy link
Collaborator Author

dkubb commented Jul 15, 2013

@mbj awesome, thanks! I'll test this out now

@dkubb
Copy link
Collaborator Author

dkubb commented Jul 15, 2013

@mbj works great. the code that triggered this bug originally works great with mutant now. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants