在Ruby中添加变量name = value格式

时间:2010-03-24 16:03:38

标签: ruby

我想为我的简单ruby函数添加一些调试,我写了一个函数,如下所示,

def debug(&block)
  varname = block.call.to_s
  puts "#{varname} = #{eval(varname,block)}"
end

debug {:x} #prints x = 5
debug {:y} #prints y = 5

我明白,eval是邪恶的。所以我有两个问题。

  1. 有没有办法在不使用eval的情况下编写调试方法?如果没有首选方法吗?
  2. 有没有办法将参数列表传递给此方法?理想情况下,我更喜欢debug {:x,:y。 :anynumOfvariables}。我无法弄清楚如何将其纳入调试方法(即,获取参数列表)

2 个答案:

答案 0 :(得分:11)

只需使用数组。您可以使用Array方法确保您始终拥有一个数组,即使有人只传入一个值:

def debug(&block)
  Array(block[]).each do |var| puts "#{var} = #{eval var.to_s, block}" end
end

x, y = 3, 5

debug {:x} # => "x = 3"
debug {[:x, :y]} # => "x = 3" "y = 5"

BTW:传递一个块作为绑定不再适用于Ruby 1.9。 (尽管文档说它 工作。)你必须明确地调用Proc#binding来获取Binding的{​​{1}}个对象:

Proc

幸运的是,这个已经在Ruby 1.8中运行,因此您可以通过包含它来保护您的代码。

另一种选择是完全放弃该区块。我的意思是,你已经强迫def debug(&block) Array(block.()).flatten.each do |var| puts "#{var} = #{eval var.to_s, block.binding}" end end 的用户使用在块中而不是在括号中传递参数的不熟悉的习惯用法。为什么不强迫他们只是传递绑定?

debug

这具有额外的灵活性,它们实际上可以传递不同的绑定而不是在呼叫站点的绑定,例如如果他们想要在应用程序的另一部分中实际调试一段代码。


顺便说一句:Ruby 1.9.2的参数内省(def debug(*vars, bnd) vars.each do |var| puts "#{var} = #{eval var.to_s, bnd}" end end x, y = 3, 5 debug :x, binding # => "x = 3" debug :x, :y, binding # => "x = 3" "y = 5" )有一些乐趣:

Proc#parameters

答案 1 :(得分:0)

我必须如何使用这些方法从每个循环中获取变量的名称和值,将它们作为嵌套哈希的键和值放置?

* attributes数组作为方法的参数传递。 我想迭代它,每个变量的名称都用作嵌套哈希值和变量值作为值的关键。

我明白了:

def get_varname(&block)
    varname = block.call.to_s
    return varname
end

def create_instance_hash(env_attrs_obj, *attributes)
    if not env_attrs_obj.has_key?("instances")
        env_attrs_obj["instances"] = ""
    end
    attributes.each do |attr|
        attr_name = get_varname{:attr}
        env_attrs_obj["instances"][attr_name] = attr
    end
end

instance_nat_ip_pub = "ip_pub_addr"
instance_nat_ip_prv = "ip_addr"
instance_nat_ami = "AMI_NAME"
instance_nat_aws_ssh_key_id = "AWS_SSH_KEY_ID"
instance_nat_id = "instance_id"

env_hash = {}

create_instance_hash(env_hash, *[instance_nat_ip_pub, instance_nat_ip_prv, instance_nat_ami, instance_nat_aws_ssh_key_id, instance_nat_id])

可是:

def attrs_each_test(*attributes)
    attributes.each do |attr|
        puts get_varname{:attr}
    end
end

它输出:

attr
attr
attr
attr
attr

错误when I run create_instance_hash

Line 12:in `[]=': string not matched (IndexError)
    from t.rb:12:in `create_instance_hash'
    from t.rb:10:in `each'
    from t.rb:10:in `create_instance_hash'
    from t.rb:24

我如何纠正此错误并实现目标?