English 中文(简体)
难道是同鲁比具有约束力的物体互动的唯一途径吗?
原标题:Is eval the only way to interact with binding objects in Ruby?

对Ruby来说,I m相当新,迄今为止,对如何使用是我最大的疼痛点之一。 如果我正确阅读文件,这些文件几乎完全不透明。 要了解约束物体内的范围,你必须携带Ruby-doc.org/Depts/Kernel.html#M005922“rel=“noretinger”>,使用约束装置。

也许我只是一个来自不同学校的纯净师,但一般说来,我很乐于修补建筑。 在一般情况下,鉴于具有约束力的物体,是否可采取任何下列措施:

  1. List the identifiers in scope in the context the binding represents, or retrieve a hash of the contents.
  2. Set the value of a local variable in the binding equal to that of some local variable in an external context. Ideally, this should work generally, even if the value is an object reference, file handle, or some other complex entity.
  3. (extension 2:) Given a hash, set locals in the binding for each entry.
  4. Better yet, given a hash build a binding with only the basic language constructs and the names in the hash in scope.

基本上,我想知道其中哪些是可能的,如何实现那些目标。 我认为,每种解决办法都将是相当密切的,这就是为什么我把所有这一切放在一个单一问题上。

另一种做法是,在具有约束力的情形下,与Perl s eval BLOCK syntax相似的,是否采用已成等法。

最佳回答

在寻找更多问题时,我找到了至少部分问题的答案:

依据:

其余是在Jim Shubert助手之后进行的试验。

  1. This can be accomplished by eval-ing local_variables, instance_variables and global_variables inside the binding.
  2. You can do something as described below, given var_name, new_val, my_binding (syntax may be imperfect or improvable, feel free to suggest in comments. Also, I couldn t get the code formatting to work inside the list, suggestions for how to do that will also be implemented.)
  3. You can straightforwardly take (2) and loop the hash to do this.
  4. See the second code block below. The idea is to start with TOPLEVEL_BINDING, which I believe normally just includes the global variables.

这确实涉及使用<代码>eval。 然而,没有将可变的数值扩大至所涉范围,因此,如果加以描述,就应当相当安全,并且应当努力采用复杂的变数值。

还指出,总是有可能做到<代码>eval var_name,本人的约束力,以便获得可变的数值。 请注意,在所有这些用途中,变数 姓名/em>至关重要。 安全的电子数据,因此理想的做法是,它不应来自任何形式的用户投入。

在具有约束力的<代码>var_ 姓名内设定一个变量,new_val,my_ binding:

# the assignment to nil in the eval coerces the variable into existence at the outer scope
setter = eval "#{var_name} = nil; lambda { |v| #{var_name} = v }", my_binding
setter.call(new_val)

建立一个具有约束力的“要发言”:

my_binding = eval "lambda { binding }", TOPLEVEL_BINDING # build a nearly-empty binding
# set_in_binding is based on the above snippet
vars_to_include.each { |var_name, new_val| set_in_binding(var_name, new_val, my_binding) }
问题回答

瓦尔特,你应当能够与具有约束力的机制直接互动。 我过去曾用过许多约束手段,但我手里有两件事:

jim@linux-g64g:~> irb
irb(main):001:0> eval "self", TOPLEVEL_BINDING
=> main
irb(main):002:0> eval "instance_variables", TOPLEVEL_BINDING
=> []
irb(main):003:0> eval "methods", TOPLEVEL_BINDING
=> ["irb_kill", "inspect", "chws", "install_alias_method", ....

我也曾提出Metaprogramming Duncan,它根本不谈具有约束力的问题。 然而,如果你照此办理,在第144页结尾处就说:

In a sense, you can see Binding objects as a "purer" form of closures than blocks, because these objects contain a scope but don t contain code.

反之,它建议绕过《继承法》(将最后两条动力移至电子呼号),看它如何使用具有约束力的文书:

// ctwc/irb/workspace.rb
eval(statements, @binding) #, file, line)

...... 我将建议通过《拉姆布达》,但我看到你刚才回答说,因此,我搁置了作为进一步研究建议。

您能否解释一下你究竟是怎样做? 请提供一些法典,说明你想如何工作。 实现你想要的东西,可能有一个更好和更安全的途径。

I m going to take a shot at guessing your typical use-case. Given a Hash: {:a => 11, :b => 22}

你们希望有一个起码、相对复杂的执行环境,使你们能够从当地人手中获得散射的价值观念。 (我不确切地确定,为什么你们需要他们成为当地人,除非你重写《发展权利宣言》,或者如果你已经制定法典,你不想适应哈希语。)

我在此试图。 简而言之,我假定你只使用符号作为哈希姆钥匙。

class MyBinding
  def initialize(varhash); @vars=varhash; end
  def method_missing(methname, *args)
    meth_s = methname.to_s
    if meth_s =~ /=z/
      @vars[meth_s.sub(/=z/,   ).to_sym] = args.first
    else
      @vars[methname]
    end
  end
  def eval(&block)
    instance_eval &block
  end
end

样本使用:

hash = {:a => 11, :b => 22}
mb = MyBinding.new hash
puts mb.eval { a + b }
# setting values is not as natural:
mb.eval { self.a = 33 }
puts mb.eval { a + b }

一些警告:

(1) 如果存在变式的斜体,我就不提姓名,而是简单的替代物,即:

def initialize(varhash)
  @vars = Hash.new {|h,k| raise NameError, "undefined local variable or method `#{k} " }
  @vars.update(varhash)
end

(2) 通常的范围规则是,如果当地人的名称与方法相同,则当地人享有优先权,除非你像(a)一样明确采用某种方法。 以上类别有相反的行为;方法优先。 为了获得“正常”行为,你需要隐藏所有(或大多数)标准方法,如“目标”等。 主动支持为此提供一种布隆克语;只有三种方法:

 __send__, instance_eval, __id__

. To use it, just make MyBinding inherit from BlankSlate. Besides these 3 methods, you also won t be able to have locals named "eval" or "method_missing".

3) 建立地方并不自然,因为它需要“自己”接受这一方法。 不能确定是否有工作。

4) 阀门可以与“@vars'h。

5) 如果你在你称之为mb.eval的地方有真正的地方var,其名称与散射钥匙之一相同,那么当地人就会享有优先权......这可能是最大的 down脚石,因为微妙的 b子可以 cr起。

我在了解我的技术后,建议使用哈希语直接保留一套变数,除非我另有说明。 但是,如果你仍然希望使用本地的电子数据,那么你可以通过使用Regexps来避免注射法,提高安全性,并且通过使用Proc等手段,“当地”规定电离层电离层电离层电离层电离层电离层电离层电离层更高。

proc { $SAFE = 1; eval "do_some_stuff" }.call  # returns the value of eval call

这里有一些基于哈希问题的解决方案。

class ScopedHash
  def initialize(varhash)
    # You can use an OpenStruct instead of a Hash, but the you lose the NameError feature.
    # OpenStructs also don t have the ability to list their members unless you call a protected method
    @vars = Hash.new {|h,k| raise NameError, "undefined local variable or method `#{k} " }
    @vars.update(varhash)
  end
  def eval
    yield @vars
  end
end

if __FILE__ == $0
  # sample usage
  hash = {:a => 11, :b => 22}
  sh = ScopedHash.new hash
  puts sh.eval {|v| v[:a] + v[:b] }
  sh.eval {|v| v[:a] = 33 }
  puts sh.eval {|v| v[:a] + v[:b] }
  sh.eval{|v| v[:c] }  # raises NameError
end

因此,除使用当地人外,你只是接触到产物。 我认为,很少有理由强迫人们操纵一个具有约束力的物体;完成任务通常有更清洁的方法。





相关问题
Ruby parser in Java

The project I m doing is written in Java and parsers source code files. (Java src up to now). Now I d like to enable parsing Ruby code as well. Therefore I am looking for a parser in Java that parses ...

rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

multiple ruby extension modules under one directory

Can sources for discrete ruby extension modules live in the same directory, controlled by the same extconf.rb script? Background: I ve a project with two extension modules, foo.so and bar.so which ...

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...