我有以下两个变量:
a = 1;
b = 'a';
我希望能够做到
SOMETYPEOFEVALUATION(b) = 2;
以便变量a
的值现在设置为2
。
a # => 2
这可能吗?
具体来说,我正在使用Facebook API。每个对象都有各种不同的连接(朋友,喜欢,电影等)。我有一个解析器类,它存储所有这些连接的最后一次调用Facebook API的状态。这些状态都被命名为与您必须调用的GET相对应,以便更新它们。
例如,要更新音乐连接,请使用https://graph.facebook.com/me/music?access_token= ...我将结果存储在名为updated_music的变量中。对于书籍,其更新的书籍。如果我创建了所有这些连接类型名称的列表,我理想地想做这样的事情。
def update_all
connection_list.each do |connection_name|
updated_SomeTypeOfEvalAndConcatenation(connection_name) = CallToAPI("https://graph.facebook.com/me/#{connection_name}?access_token=...")
end
end
Rails和StackOverflow都是新手,所以如果有更好的方法可以遵循任何约定,请告诉我。
尝试以下方法。
class FacebookParser
attr_accessor :last_albums_json,
def update_parser_vars(service)
handler = FacebookAPIHandler.new
connections_type_list = ['albums']
connections_type_list.each do |connection_name|
eval "self.last_#{connection_name}_json = handler.access_api_by_content_type(service, #{connection_name})['data']"
end
#self.last_albums_json = handler.access_api_by_content_type(service, 'albums')['data']
end
end
我收到此错误
undefined local variable or method `albums' for #<FacebookParser:0xaa7d12c>
当我使用已注释掉的行时,工作正常。
答案 0 :(得分:3)
像这样改变一个不相关的变量有点代码味道;当变量神奇地改变值时,大多数程序员都不喜欢它,至少不是在一个封闭的类中。
在这个简单的例子中,更常见的是:
a=something(b)
或者如果a是一个更复杂的东西,那就把它变成一个类:
class Foo
attr_accessor :a
def initialize(value)
@a = value
end
def transform(value)
@a = "new value: #{value}"
end
end
baz = "something"
bar = Foo.new(2)
bar.a
=> 2
bar.transform(baz)
bar.a
=> "new value: something"
因此,虽然第二个示例更改了内部变量但未通过访问器更改,但至少它是具有有限API的封装对象的一部分。
更新啊,我认为问题是如何处理php的variable variables。正如穆建议的那样,如果你想这样做,你可能做错了事......这是一个永远不应该被想到的概念。使用类或哈希或其他东西。
答案 1 :(得分:1)
怎么样
eval "#{b}=2"
使用实例变量,您也可以执行instance_variable_set("@name", value)
编辑:
如果你定义了一个setter(你有),你也可以使用send
方法,试试这个:
class FacebookParser
attr_accessor :last_albums_json,
def update_parser_vars(service)
handler = FacebookAPIHandler.new
connections_type_list = ['albums']
connections_type_list.each do |connection_name|
send("last_#{connection_name}_json=",
handler.access_api_by_content_type(
service, connection_name)['data']))
end
end
end
原始代码的问题是
eval ".... handler.access_api_by_content_type(service, #{connection_name})"
将执行
... handler.access_api_by_content_type(service, albums)
# instead of
... handler.access_api_by_content_type(service, 'albums')
所以你必须写
eval ".... handler.access_api_by_content_type(service, '#{connection_name}')" <- the quotes!
这就是人们通常避免使用eval的原因 - 很容易犯这种错误
答案 2 :(得分:0)
这些事情通常不是使用Ruby中的局部变量及其名称来完成的。通常的方法可能包括哈希和符号:
data = Hash.new
data[:a] = 1 # a = 1
b = :a # b = 'a'
然后,稍后
data[b] = 2 # SOMETYPEOFEVALUATION(b) = 2
data[:a] # => 2