Project

General

Profile

Actions

Feature #16783

closed

Implicit vs explicit self

Added by koriroys (Kori Roys) almost 4 years ago. Updated almost 4 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:97870]

Description

I recently ran into this case while trying to explain why self is needed for calling setters (can't disambiguate between creating a local variable versus calling the setter because of the syntactic sugar). However, I couldn't come up with a good reason why self throws an error when calling private getters. It feels inconsistent? I think it would be more consistent to be able to specify self.private_getter and self.private_setter = "value", though I don't know the implications. Would this be possible? Would people appreciate this?

class Thing

  # works
  def public_method_calling_private_setter_with_explicit_self
    self.name = "value"
  end
  
  # works, but doesn't call the private setter
  # common beginner mistake
  def public_method_creating_local_variable
    name = "whoops!"
  end
  
  # works
  def public_getter_accessing_instance_variable
    @name
  end
  
  # works
  def public_getter_calling_private_getter_with_implicit_self
    private_name
  end

  # DOES NOT work
  def public_getter_calling_private_getter_with_explicit_self
    self.private_name
  end

  private
  def name=(value)
    @name = value
  end
  
  def private_name
    @name
  end
end

thing = Thing.new
thing.public_getter_accessing_instance_variable #=> nil
thing.public_method_calling_private_setter_with_explicit_self # => "value"
thing.public_getter_accessing_instance_variable #=> "value"

thing.public_method_creating_local_variable # => "whoops!"
# instance variable unchanged
thing.public_getter_accessing_instance_variable # => "value"

thing.public_getter_calling_private_getter_with_implicit_self # => "value"

# should this work?
thing.public_getter_calling_private_getter_with_explicit_self # => NoMethodError (private method `private_name' called for Thing)

Updated by koriroys (Kori Roys) almost 4 years ago

  • Description updated (diff)

phrasing

Updated by jeremyevans0 (Jeremy Evans) almost 4 years ago

  • Status changed from Open to Closed

This was implemented in Ruby 2.7:

class A
  def b
    self.a
    self.a = 1
  end
  private
  attr_accessor :a
end
p A.new.b
# 2.7: 1
# 2.6 and below: NoMethodError

See #11297 and #16123.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0