ruby 对象定义_Ruby中定义的关键字

ruby 对象定义

In this article, we’re going to explore the following topics:

在本文中,我们将探讨以下主题:

  • the defined? keyword

    defined? 关键词

  • defined? in the context of resolv-replace

    defined? 在解决resolv-replace的背景下

  • defined? yield vs block_given?

    defined? yield defined? yield vs block_given?

开始之前 (Before to start)

I’m thrilled to share with you our latest project: Fun Facts about Ruby — Volume 1

我很高兴与您分享我们的最新项目:有关Ruby的有趣事实-第1卷

Please feel free to spread the word and share this link! 🙏

请随时宣传并分享此链接! 🙏

Thank you for your time!

感谢您的时间!

定义的? 关键词 (The defined? keyword)

In Ruby, the defined? keyword returns a string that represents the type of the entity passed as argument. Here is an exhaustive list of what you can pass to defined?

在Ruby中, defined? 关键字返回一个字符串,该字符串表示作为参数传递的实体的类型。 以下是您可以传递给defined?的详尽列表defined?

defined? String # => "constant"
defined? puts   # => "method"
defined? [1, 2] # => "expression"


@@a, @a, a = 21, 42, 84
defined? @aa   # => "class variable"
defined? @a    # => "instance-variable"
defined? a     # => "local-variable"
defined? a = 2 # => "assignment"
defined? $$    # => "global-variable"


def hello
  defined? yield
end


hello {} # => "yield"


class A
  def hello; end
end


class B
  def hello
    defined? super
  end
end


B.new.hello # => "super"

Here, we can see that defined? handles a maximum of cases. But some cases are more relevant than others. For example, let’s see how the resolv-replace library — available in the Ruby Standard Library — takes advantage of this keyword to handle a really “tricky” case.

在这里,我们可以看到defined? 处理最多案件。 但是有些情况比其他情况更相关。 例如,让我们看看Ruby Standard Library中提供的resolv-replace库如何利用此关键字来处理真正的“棘手”情况。

定义的? 在解决resolv-replace的背景下 (defined? in the context of resolv-replace)

This library simply monkey-patches (IP|TCP|UDP|SOCKS)Socket classes provided by the socket library to use the Resolv DNS resolver.

该库只是对socket库提供的(IP|TCP|UDP|SOCKS)Socket(IP|TCP|UDP|SOCKS)Socket猴子修补,以使用Resolv DNS解析器

In the case of SOCKSSocket, the monkey-patching only intervenes when the Ruby interpreter is compiled with the --enable-socks flag. So let’s see how the resolv-replace library handles this tricky case

对于SOCKSSocket ,仅当使用--enable-socks标志编译Ruby解释器时,才会进行猴子修补。 那么,让我们看看resolv-replace库如何处理这个棘手的情况

# in lib/resolv-replace.rb


class SOCKSSocket < TCPSocket
  # :stopdoc:
  alias original_resolv_initialize initialize
  # :startdoc:
  def initialize(host, serv)
    original_resolv_initialize(IPSocket.getaddress(host), port)
  end
end if defined? SOCKSSocket

Notice the modifier-if line 10. Indeed, to choose to monkey-patch this class or not, the resolv-replace library simply checks if the SOCKSSocket constant is defined using the defined? keyword. Indeed, as seen in the previous section, SOCKSSocket is only defined if the Ruby interpreter is compiled using the --enable-flag.

请注意修饰符- if第10行。的确,要选择是否对此类进行猴子修补, resolv-replace库仅检查SOCKSSocket常量是否使用已defined? 关键词。 确实,如上一节所述,仅当使用--enable-flag编译Ruby解释器时,才定义SOCKSSocket

So, as the class keyword is only a syntactic sugar for class definition and class opening, then you can call a modifier-if to execute this code (or not).

因此,由于class关键字只是用于类定义和类打开的语法糖,因此您可以调用修饰符-if以执行此代码(或不执行)。

Now let’s see how using defined? can positively impact the performances of your application.

现在让我们看看如何使用defined? 可以对应用程序的性能产生积极影响。

(收益率)vs block_given? (defined?(yield) vs block_given?)

If in your program you deal with a huge amount of blocks, then defined? yield can definitely become a real optimization for your program performance. Indeed, to check if a block is passed to your method, you normally use the Kernel#block_given? method

如果在您的程序中您处理了大量的块,那么defined? yield defined? yield绝对可以成为您程序性能的真正优化。 确实,要检查是否将块传递给您的方法,通常使用Kernel#block_given? 方法

def method_with_block_given
  yield if block_given?
end


method_with_block_given { 42 } # => 42
method_with_block_given        # => nil

Here method_with_block_given checks if a block is passed as argument by using Kernel#block_given?. If so, then yield is called and the block is executed. Otherwise, block_given? returns false and yield is never executed.

这里method_with_block_given通过使用Kernel#block_given?检查是否将块作为参数传递Kernel#block_given? 。 如果是这样,则调用yield并执行该块。 否则, block_given? 返回false并且永不执行yield

Ruby provides another way to achieve the same result: defined?(yield)

Ruby提供了另一种获得相同结果的方法: defined?(yield)

def method_with_defined_yield
  yield if defined?(yield)
end


method_with_defined_yield {42} # => 42
method_with_defined_yield      # => nil

The main difference between these 2 expressions is that defined?(yield) is faster than Kernel#block_given?. Indeed, it’s a keyword when the block_given? is a method. So block_given? is slower because of the cost of the method call added to the cost of the Method Lookup Path.

这两个表达式之间的主要区别在于,已defined?(yield)Kernel#block_given? 。 确实,当block_given?时,它是一个关键字block_given? 是一种方法。 那么block_given? 由于方法调用的成本增加了方法查找路径的成本,因此速度较慢。

Let’s generate benchmark-ips reports to see what’s the difference between defined?(yield) and block_given?

让我们生成benchmark-ips报告,以查看block_given? defined?(yield)block_given?之间有什么区别block_given?

require 'benchmark/ips'


def method_with_block_given
  yield if block_given?
end


def method_with_defined_yield
  yield if defined?(yield)
end




Benchmark.ips do |x|
  x.config(:time => 5, :warmup => 2)


  x.report("block_given?") { method_with_block_given {42} }
  x.report("defined? yield") { method_with_defined_yield {42} }


  x.compare!
end

We can see that block_given? is 1.27x slower than defined?(yield).

我们可以看到那个block_given?defined?(yield)速度慢1.27倍defined?(yield)

But as seen in the above benchmark, we’re able to call block_given 9.897M times in a second. So keep in mind that this optimization is only relevant on a huge amount of block calls.

但是从上述基准中可以看出,我们能够在一秒钟内调用block_given 9.897M次。 因此请记住,此优化仅与大量的块调用有关。

结论 (Conclusion)

defined? isn’t the most popular keyword in Ruby. Nevertheless, in some situations this keyword becomes a powerful asset to enhance your program performance or to handle tricky cases where a constant, method, etc.. is conditionally loaded. Please feel free to share with us your experience with this keyword in the comments section.

defined? 不是Ruby中最受欢迎的关键字。 但是,在某些情况下,此关键字成为增强程序性能或处理有条件地加载常量,方法等的棘手情况的强大资产。 请随时在评论部分与我们分享您使用此关键字的经验。

Voilà!

瞧!

松尾芭蕉的“老池塘” (“The Old Pond” by Matsuo Bashō)

An old silent pond

一个古老的无声池塘

A frog jumps into the pond —

一只青蛙跳进池塘里—

Splash! Silence again.

溅! 再次沉默。

翻译自: https://medium.com/rubycademy/the-defined-keyword-in-ruby-b7a5a5a48e1e

ruby 对象定义

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值