为什么Ruby setter方法返回字符串而不是符号作为最后一个计算表达式? 方法的意外返回值:应为符号
我有以下的机票等级:为什么Ruby setter方法返回字符串而不是符号作为最后一个计算表达式? 方法的意外返回值:应为符号,ruby,string,casting,symbols,setter,Ruby,String,Casting,Symbols,Setter,我有以下的机票等级: class Ticket VALID_STATES = %i[open closed invalid wontfix] attr_reader :status def status= new_state new_state = new_state.to_sym @status = new_state end end 当传递字符串而不是符号时,setter方法意外地返回字符串,即使getter方法返回的是正确的值。例如: t = Ticket
class Ticket
VALID_STATES = %i[open closed invalid wontfix]
attr_reader :status
def status= new_state
new_state = new_state.to_sym
@status = new_state
end
end
当传递字符串而不是符号时,setter方法意外地返回字符串,即使getter方法返回的是正确的值。例如:
t = Ticket.new
t.status = 'closed'
#=> "closed"
t.status
#=> :closed
看起来正确的值被存储为一个符号,但我不知道为什么当最后一个计算的表达式应该返回:closed
时,该方法在REPL返回“closed”
。我的期望是,所讨论的表达式应该解析为@status=:closed
,因此应该返回一个符号
有人能解释为什么我从setter方法得到一个字符串而不是一个符号作为返回值吗
注意事项和防止自行车脱落
@status=new\u state.to\u sym
而不是分配回new\u state,但是有一个中间代码被删除以创建这个最小的示例。我不想对代码做太多的修改,因为这样就无法显示我真正的代码在做什么。不管怎么说,这似乎对这个具体问题没有什么影响;我试过两种方法deffoo=(str)的替代抽象进行调试@foo=str.to_sym;end
进一步引导兔子洞def a=(value)
return 1 + value
end
p(a = 5) # prints 5
Ruby允许您链接分配:
foo = bar = 'closed'
上面将指定为“关闭”
,foo
和bar
通过返回参数并忽略方法的返回值,可以使用方法调用替换bar
:
foo = t.status = 'closed'
在我看来,如果上面将:closed
分配给foo
,那将非常令人惊讶
如果确实需要返回值,请使用send
或public\u send
:
def a=(value)
return 1 + value
end
p(a = 5) # prints 5
p(send(:a=, 5)) # prints 6
答案很简单:在Ruby中,赋值根据被赋值来计算。方法分配没有什么特别之处。我真的很喜欢这些准备充分的问题感谢文档的链接。你是对的,这似乎是一个仅适用于赋值方法(而不是赋值表达式)的文档化的小案例,但这仍然让我感到惊讶,因为我期望的行为与
foo='a'。to_sym#=>:a
相同。但显然情况并非如此/我经常同意你的答案,但在这种情况下我不能。在方法内部,指定的值是一个符号。因此,当文档为不同的行为调用方法赋值时,“赋值”是一个符号,而不是字符串。@CodeGnome是两个不同的赋值。您的方法中有@status=new\u state
,其计算结果为new\u state
(即:closed
)。您的方法之外有t.status='closed'
,该方法的计算结果为“closed”
。内部赋值不会以任何方式影响外部赋值。返回值始终是右侧的值。