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

Allow self.Foo #628

Merged
merged 1 commit into from
Dec 4, 2013
Merged

Allow self.Foo #628

merged 1 commit into from
Dec 4, 2013

Conversation

chulkilee
Copy link
Contributor

omitting self in self.Foo gives uninitialized constant NameError

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling 6fe373355da502b689b6d1229a6d09832125e2e8 on chulkilee:allow-self into 62a7059 on bbatsov:master.

@bbatsov
Copy link
Collaborator

bbatsov commented Nov 12, 2013

I'm not sure I understand the nature of this problem. If the constant was defined at this point it would surely be accessible without self.

@jonas054
Copy link
Collaborator

@bbatsov I think it's this case. You need self. to call B, otherwise you get uninitialized constant Klass::B (NameError).

class Klass
  def A
    puts 'A'
    self.B
  end

  def B
    puts 'B'
  end
end

Klass.new.A

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling b89939eb9d6417910f5af46fbbdd15446e33c33a on chulkilee:allow-self into dc7544f on bbatsov:master.

@chulkilee
Copy link
Contributor Author

self cannot be omitted when the method name can be recognized as constant (/^A-Z/), because it just behaves differently.

Foo = 3

class Klass
    def method_missing(meth, *args, &block)
      "missing #{meth}"
    end

    def test
      self.Foo
    end

    def test_constant
      Foo
    end
end

puts Klass.new.test
puts Klass.new.test_constant

@agrimm
Copy link
Contributor

agrimm commented Nov 13, 2013

You can also do Foo(), which has been allowed by RuboCop since #585

Foo = 3

class Klass
  def method_missing(meth, *args, &block)
    "missing #{meth}"
  end

  def test
    self.Foo
  end

  def test_constant
    Foo
  end

  def test_parentheses
    Foo()
  end
end

puts Klass.new.test
puts Klass.new.test_constant
puts Klass.new.test_parentheses

@chulkilee
Copy link
Contributor Author

First, self.Foo and Foo is different, so self.Foo should not be considered as "redundant" - it's rubocop bug.

Second, as @agrimm mentioned, that self can be replaced with method call. Then should it be avoided? (This is somewhat different topic)

I think calling self.Foo sounds more like attribute than Foo() so there are some cases self.Foo is more natural. See the following example.

class Original
  def Id
    "fake id"
  end
end

class Wrapper
  def initialize(raw)
    @raw = raw
  end

  def details
    "#{self.Id}"
  end

  def method_missing(meth, *args, &block)
    @raw.send(meth)
  end
end

original = Original.new
wrapper = Wrapper.new(original)
puts wrapper.details

Wrapper#Id is more like attribute rather than method - which can be done by omitting parenthesis (which is absolutely legit in ruby)

This is the case when I need to wrap a restfoce object. restforce uses hashie to wrap Salesforce response, which includes camel case attributes (like Id, Name etc).

If we want to add rules to discourage using camel case method name, that should be another cop, not in this RedundantSelf cop.

omitting `self` in `self.Foo` gives uninitialized constant NameError
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.07%) when pulling 5e9d697 on chulkilee:allow-self into e4b7f67 on bbatsov:master.

@bbatsov
Copy link
Collaborator

bbatsov commented Dec 3, 2013

@jonas054 @yujinakayama I'm not sure what's the best way to handle this, since CamelCase methods are quite rare and generally used only for conversions. Maybe the best option would be to implement this as an option - AllowConstants or something like this. Furthermore, there is the (small) possibility of confusing an actual constant (for which self would truly be redundant) with a camelcase method name.

@jonas054
Copy link
Collaborator

jonas054 commented Dec 3, 2013

Since both self.UpperCaseMethod and self.CONSTANT are rare, I think @chulkilee's solution is OK. False positives are really bad. False negatives in rare cases, we can live with.

@bbatsov bbatsov merged commit 5e9d697 into rubocop:master Dec 4, 2013
@bbatsov
Copy link
Collaborator

bbatsov commented Dec 4, 2013

Sounds reasonable.

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

Successfully merging this pull request may close these issues.

5 participants