繁体   English   中英

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

[英]Putting a variable name = value format in 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}。 我无法弄清楚如何将其纳入调试方法(即,获取参数列表)

只需使用数组。 您可以使用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来获取该ProcBinding对象:

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

幸运的是,这已经适用于Ruby 1.8,因此您可以通过包含它来保护您的代码。

另一种方法是完全放弃该块。 我的意思是,你已经强制debug的用户使用在块中而不是在括号中传递参数的不熟悉的习惯用法。 为什么不强迫他们只是通过绑定呢?

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"

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


顺便说一句:Ruby 1.9.2的参数内省( Proc#parameters )有一些乐趣:

def debug(&block)
  block.parameters.map(&:last).each do |var|
    puts "#{var} = #{eval var.to_s, block.binding}"
  end
end

x, y = 3, 5

debug {|x|} # => "x = 3"
debug {|x, y|} # => "x = 3" "y = 5"

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

* 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

运行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

我如何纠正这个错误并实现我的目标?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM