就像JavaScript一样,在ruby中,lambda可以通过函数传递。
在JavaScript this中将解析为调用者对象。
但是红宝石呢?同样的机制也适用于红宝石的lambda或块吗?怎么样?能给我一些示例代码吗?
顺便说一句,我已经阅读了Ruby编程语言,但是从中找不到任何有用的信息。
在Ruby中,它self是按词法作用域划分的,即,self在块或lambda中的内容就是在同一位置而不在块或lambda中的情况。
class << foo = Object.new
def bar
puts "`self` inside `foo#bar` is #{self.inspect}"
yield self
end
end
this = self
foo.bar do |that|
puts "`self` inside the block is #{self.inspect}"
case
when this.equal?(self)
puts "… which is the same as outside the block."
when that.equal?(self)
puts "… which is the same as inside the method."
else
puts "Ruby is really weird, `self` is something completely different!"
end
end
# `self` inside `foo#bar` is #<Object:0xdeadbeef48151623>
# `self` inside the block is main
# … which is the same as outside the block.
Run Code Online (Sandbox Code Playgroud)
这也适用于lambda:
class << foo = Object.new
def bar(lambda)
# ????????
puts "`self` inside `foo#bar` is #{self.inspect}"
lambda.(self)
#????????????
end
end
this = self
foo.bar(-> that do
# ????????
puts "`self` inside the lambda is #{self.inspect}"
case
when this.equal?(self)
puts "… which is the same as outside the lambda."
when that.equal?(self)
puts "… which is the same as inside the method."
else
puts "Ruby is really weird, `self` is something completely different!"
end
end)
# `self` inside `foo#bar` is #<Object:0xdeadbeef48151623>
# `self` inside the lambda is main
# … which is the same as outside the lambda.
Run Code Online (Sandbox Code Playgroud)
还有的,但是,那非常具体的反射方式固定数量的做变化self,这些都是在方法*_{exec|eval}的家庭:
BasicObject#instance_execModule#module_execBasicObject#instance_evalModule#module_evalClass#module_eval示例(仅从上方更改一条相关行):
class << foo = Object.new
def bar(&blk)
# ??????
puts "`self` inside `foo#bar` is #{self.inspect}"
instance_exec(self, &blk)
#????????????????????????
end
end
this = self
foo.bar do |that|
puts "`self` inside the block is #{self.inspect}"
case
when this.equal?(self)
puts "… which is the same as outside the block."
when that.equal?(self)
puts "… which is the same as inside the method."
else
puts "Ruby is really weird, `self` is something completely different!"
end
end
# `self` inside `foo#bar` is #<Object:0xdeadbeef48151623>
# `self` inside the block is #<Object:0xdeadbeef48151623>
# … which is the same as inside the method.
# ??????????????????
Run Code Online (Sandbox Code Playgroud)
这也适用于lambda(转换为块):
foo.bar(&-> that do
# ????????
puts "`self` inside the lambda is #{self.inspect}"
case
when this.equal?(self)
puts "… which is the same as outside the lambda."
when that.equal?(self)
puts "… which is the same as inside the method."
else
puts "Ruby is really weird, `self` is something completely different!"
end
end)
# `self` inside `foo#bar` is #<Object:0xdeadbeef48151623>
# `self` inside the lambda is #<Object:0xdeadbeef48151623>
# … which is the same as inside the method.
# ??????????????????
Run Code Online (Sandbox Code Playgroud)
最后,Ruby允许您将特定调用位置的词法环境反射性地Binding对象化为对象。然后,您可以使用绑定的Binding#eval方法或将绑定对象传递给Kernel#eval:在此特定绑定的上下文中评估代码
class << foo = Object.new
def bar(str)
puts "`self` inside `foo#bar` is #{self.inspect}"
binding.eval(str)
#????????????????
end
end
$this = self
foo.bar <<~'HERE'
puts "`self` inside the eval'd string is #{self.inspect}"
if $this.equal?(self)
puts "… which is the same as outside the eval'd string."
end
HERE
# `self` inside `foo#bar` is #<Object:0x0070070070070070>
# `self` inside the eval'd string is #<Object:0x0070070070070070>
Run Code Online (Sandbox Code Playgroud)
self是Ruby 中三个隐式上下文之一:
selfyugui上有一篇不错的博客文章,主要讨论默认的definee,但同时也简要介绍了self:Ruby中的三个隐式上下文。日语中还有一篇较旧的文章,其中有更多细节:Ruby ???????????????? (3)-??? 。
| 归档时间: |
|
| 查看次数: |
54 次 |
| 最近记录: |