#ruby #struct
#ruby #структура
Вопрос:
Я новичок в Ruby, в настоящее время я собираюсь использовать Struct в классе, чтобы создать временный объект. Однако я сталкиваюсь с вопросом, когда я использую член в структуре, подобной этой:
class A
attr_accessor :b
B = Struct.new(:name, :print_name) do
def print_name
p "Hello #{name}"
end
end
def initialize(input_name)
@b = B.new(input_name)
end
end
a = A.new('Leo')
a.b.print_name # Hello Leo
Но я также получаю тот же результат, когда мои параметры Struct B не включены :print_name
.
B = Struct.new(:name) do
...
end
Так в чем же разница? И когда я должен использовать параметр члена, а когда нет?
Спасибо
Ответ №1:
В первом случае вы определяете класс, инициализатор которого принимает два аргумента — name
и print_name
.
Во втором случае вы определяете класс, инициализатор которого принимает один аргумент — name
.
Это не имеет ничего общего с тем фактом, что вы определяете вызываемый метод экземпляра print_name
.
Таким образом, экземпляры обоих классов (с print_name
аргументом и без него) имеют print_name
определенный метод, поэтому оба примера работают одинаково.
Разница будет видна при проверке созданных объектов:
# first case with two arguments
foo = B.new(:a, :b)
foo.inspect
=> "#<struct B name=:a, print_name=:b>"
# second case with single argument
foo = B.new(:a)
foo.inspect
=> "#<struct B name=:a>"
Кроме того, когда вы проверите методы экземпляра класса B для обоих случаев, вы сможете увидеть разницу:
# first case with two arguments
B.instance_methods false
#=> [:name, :name=, :print_name, :print_name=]
# second case with single argument
B.instance_methods false
#=> [:name, :name=, :print_name]
Но я также получаю тот же результат, когда мои параметры Struct B не
включают:print_name
Разница в том, что в первом случае вы можете выполнить следующее:
a.b.print_name = 'new print name'
a.b.inspect
#=> "#<struct B name='Leo', print_name='new print name'>"
Тогда как во втором случае он завершится неудачей:
a.b.print_name = 'new print name'
#=> NoMethodError: undefined method 'print_name=' for #<struct B name='Leo'>