In Ruby, can I give access to a protected method to a different specified class?

StackOverflow https://stackoverflow.com/questions/22725071

  •  23-06-2023
  •  | 
  •  

For example, I'd like to do something like this

class Child
  @name = "Bastion, please, call my name!"
  attr_reader :name
end

class Parent
  @name = "I am a parent"
  def rename_child(child,name)
    child.name = name
  end
end

bastion = Parent.new()
princess = Child.new()

bastion.rename_child(princess,"Moon Child")

I only want instances of the Parent class to be able to change the @name of a Child class.

EDIT

I only want instances of the Parent class to be able to change the @name of a Child instance.

有帮助吗?

解决方案

I'm assuming you meant for @name to be an instance variable, rather than a class instance one...if my hunch is right, you can do this using #send:

class Child
  def initialize
    @name = "Bastion, please, call my name!"
  end
  attr_reader :name
  private
  attr_writer :name
end

class Parent
  def initialize
    @name = "I am a parent"
  end
  def rename_child(child, name)
    child.send(:name=, name)
  end
end

bastion, princess = Parent.new, Child.new

p princess.name
#=> "Bastion, please, call my name!"

bastion.rename_child(princess, "Moon Child")

p princess.name
#=> "Moon Child"

其他提示

No you cannot do that. The problem is not the method being private. You cannot access a class instance variable by an accessor defined on an instance.

This is unfortunately not possible. The closest you can get is:

class Child
  @name = "Bastion, please, call my name!"
  attr_reader :name
end

class Parent
  @name = "I am a parent"
  def rename_child(child,name)
    child.instance_variable_set(:@name, name)
  end
end

Note that instance_variable_set is a public method, which together with eval makes private/public differences in ruby not to be so strict as in other languages. Those methods should be use extremely cautiously and they are usually considered to be slightly 'hacky'.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top