我在a library中有以下代码,有人可以解释一下以下代码中的代码(“#{k} =“)是什么意思吗?
if respond_to?("#{k}=")
public_send("#{k}=", v)
else
raise UnknownAttributeError.new(self, k)
end
我了解到response_to是Ruby中的默认函数,但该语法没有定义/解释,请帮助我们。
已编辑:
我收到上述代码的异常(unknown attribute 'token' for PersonalAccessToken. (ActiveModel::UnknownAttributeError)
)
/opt/gitlab/embedded/lib/ruby/gems/2.5.0/gems/activemodel-5.0.7.1/lib/active_model/attribute_assignment.rb:40:in `block in _assign_attributes'
/opt/gitlab/embedded/lib/ruby/gems/2.5.0/gems/activemodel-5.0.7.1/lib/active_model/attribute_assignment.rb:48:in `_assign_attribute': unknown attribute 'token' for PersonalAccessToken. (ActiveModel::UnknownAttributeError)
因此,将k视为“令牌”,在哪种情况下我会得到异常(在哪种情况下会进入else状态?)
答案 0 :(得分:1)
此代码public_send("#{k}=", v)
动态调用setter来存储k
变量中的内容。考虑以下示例:
class FooBarBaz
attr_accessor :foo, :bar, :baz
def set_it what, value
public_send("#{what}=", value)
end
end
大致相当于:
def set_it what, value
case what
when "foo" then public_send("foo=", value)
when "bar" then public_send("bar=", value)
when "baz" then public_send("baz=", value)
end
end
大致相当于:
def set_it what, value
case what
when "foo" then self.foo=(value)
...
end
end
大致相当于:
def set_it what, value
case what
when "foo" then self.foo = value
...
end
end
respond_to?
来检查此实例上是否确实为此k
定义了setter,以防止出现以下情况:
FooBarBaz.new.set_it :inexisting, 42
#⇒ NoMethodError: undefined method `inexisting=' for #<FooBarBaz:0x0056247695a538>
此答案中该类的修改后的正确版本:
class FooBarBaz
attr_accessor :foo, :bar, :baz
def set_it what, value
public_send("#{what}=", value) if respond_to?("#{what}=")
end
end
它不会引发异常。
FooBarBaz.new.set_it :inexisting, 42
#⇒ nil
答案 1 :(得分:0)
“#{}”是红宝石中的字符串插值。例如:
PS C:\nodejs\prod\monetrum-node-client> npm unpublish monetrum-node-
client --force
npm WARN using --force I sure hope you know what you are doing.
npm ERR! code E400
npm ERR! You can no longer unpublish this version. Please deprecate it
instead
npm ERR! npm deprecate -f 'monetrum-node-client@*' "this package has
been deprecated" : 12-7be182ce2a14ca2bb34c07a7707a75c0
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\HP\AppData\Roaming\npm-cache\_logs\2019-04-
01T12_24_19_378Z-debug.log
PS C:\nodejs\prod\monetrum-node-client>
因此在您的示例中,它看起来像是在创建一个值为k和=
的字符串例如
k = 'world'
puts "hello #{k}"
# hello world
如果您想知道k是什么,可以在上面的行中添加k = 'something'
"#{k}="
# something=
,然后运行代码并检查控制台。
如果您使用的是类似RubyMine的更好,则只需使用调试器并在该行上插入断点即可。
答案 2 :(得分:-1)
我认为您在this docs中看到了_assign_attribute
方法
k是'key'的缩写含义,v是'value'的同义含义
"#{k}="
是通过字符串文字转换为动态方法的某种方法名称。
可能是“更新”或“创建”,“拆分”等任何内容。
等号(“ =”)的含义是它们是分配诸如此类user.attributes = { :username => 'Phusion', :is_admin => true }
在上述情况下,“ k”为.attributes
,“ k =“为attributes=
,“ v”为{ :username => 'Phusion', :is_admin => true }
public_send
是在公共范围内发送方法的方法。
因此,public_send("#{k}=", v)
的含义是在公共方法中调用名称为“ k”的方法,并且该方法将被分配给值“ v”。
我希望这对您有所帮助。
添加一些评论示例
k是程序员的输入,因此它与“类”或“模块”中的方法名称不匹配。
实际上,有常见的错误情况。
class User
# this attribute can be called from a instance of User
attr_accessor :name
end
# this causes a error when call assign_attribute
User.new.wrong_name
# this is fine
User.new.name