Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby与PHP的等价物是什么;它很紧凑吗?_Php_Ruby - Fatal编程技术网

Ruby与PHP的等价物是什么;它很紧凑吗?

Ruby与PHP的等价物是什么;它很紧凑吗?,php,ruby,Php,Ruby,考虑到一些问题,在Ruby中最简单的方法是什么 def foo name = 'David' age = 25 role = :director ... # How would you build this: # { :name => 'David', :age => 25, :role => :director } # or # { 'name' => 'David', 'age' => 25, 'role' => :dire

考虑到一些问题,在Ruby中最简单的方法是什么

def foo
  name = 'David'
  age = 25
  role = :director
  ...
  # How would you build this:
  # { :name => 'David', :age => 25, :role => :director }
  # or
  # { 'name' => 'David', 'age' => 25, 'role' => :director }
end
在PHP中,我可以简单地执行以下操作:

$foo = compact('name', 'age', 'role');

我的原始答案有了很大的改进。如果从
绑定本身继承,则会更干净。之所以有
to_sym
,是因为较早版本的ruby将
局部变量
作为字符串

实例方法

class Binding
  def compact( *args )
    compacted = {}
    locals = eval( "local_variables" ).map( &:to_sym )
    args.each do |arg|
      if locals.include? arg.to_sym
        compacted[arg.to_sym] = eval( arg.to_s ) 
      end 
    end 
    return compacted
  end
end
def compact( *args, &prok )
  compacted = {}
  args.each do |arg|
    if prok.binding.send( :eval, "local_variables" ).include? arg
      compacted[arg.to_sym] = prok.binding.send( :eval, arg ) 
    end
  end 
  return compacted
end
用法

foo = "bar"
bar = "foo"
binding.compact( "foo" ) # => {:foo=>"bar"}
binding.compact( :bar ) # => {:bar=>"foo"}
foo = "bar"
compact( "foo" ){}
# or
compact( "foo", &proc{} )

原始答案

这是我能找到的最接近Php的方法-

方法

class Binding
  def compact( *args )
    compacted = {}
    locals = eval( "local_variables" ).map( &:to_sym )
    args.each do |arg|
      if locals.include? arg.to_sym
        compacted[arg.to_sym] = eval( arg.to_s ) 
      end 
    end 
    return compacted
  end
end
def compact( *args, &prok )
  compacted = {}
  args.each do |arg|
    if prok.binding.send( :eval, "local_variables" ).include? arg
      compacted[arg.to_sym] = prok.binding.send( :eval, arg ) 
    end
  end 
  return compacted
end
示例用法

foo = "bar"
bar = "foo"
binding.compact( "foo" ) # => {:foo=>"bar"}
binding.compact( :bar ) # => {:bar=>"foo"}
foo = "bar"
compact( "foo" ){}
# or
compact( "foo", &proc{} )

但这并不完美,因为你必须通过一个进程。我愿意接受关于如何改进这一点的建议。

这是Bungus答案的一个变体,但这里有一个明显更难看的单行线,但不扩展绑定或任何内容:

foo = :bar
baz = :bin
hash = [:foo, :baz].inject({}) {|h, v| h[v] = eval(v.to_s); h }
# hash => {:baz=>:bin, :foo=>:bar}
您还可以通过滥用块绑定使其看起来有点像一个方法调用,这也是Bungus原始答案的一个变体:

module Kernel
  def compact(&block)
    args = block.call.map &:to_sym
    lvars = block.binding.send(:eval, "local_variables").map &:to_sym
    (args & lvars).inject({}) do |h, v|
      h[v] = block.binding.send(:eval, v.to_s); h
    end
  end
end

foo = :bar
baz = :bin
compact {[ :foo, :bar, :baz ]}
# {:foo=>:bar, :baz=>:bin}
(我会告诉自己,
{[…]}
是垃圾压实机的符号。)

如果您使用调用者的
binding\u
gem,您可以同时放弃proc和显式绑定:

require 'binding_of_caller'
module Kernel
  def compact(*args)
    lvars = binding.of_caller(1).send(:eval, "local_variables").map &:to_sym
    (args.map(&:to_sym) & lvars).inject({}) do |h, v|
      h[v] = binding.of_caller(2).send(:eval, v.to_s); h
    end
  end
end

foo = :bar
baz = :bin
compact :foo, :bar, :baz
# {:foo=>:bar, :baz=>:bin}

请注意,速度很慢。在生产代码中,您可能永远都不应该尝试这样做,而应该保留一个散列值,这样在您睡觉时维护它的程序员就不会找到您并杀死您。

我真的对PHP允许这种异常…,嗯,非正统代码感到困惑。
compact
是否真的按名称获取局部变量并从另一个函数中访问它们?似乎您可以将
eval
置于循环之外,不是吗?