Understanding Ruby Singleton Classes - Contextual Development

foobar = Array.new

def foobar.size
  "Hello World!"
end

foobar.size  # => "Hello World!"
foobar.class # => Array

bizbat = Array.new
bizbat.size  # => 0
When you add a method to a specific object, Ruby inserts a new, anonymous class into the inheritance hierarchy as a container to hold these types of methods.

More Ways to Skin a Singleton:

module Foo
  def foo
    "Hello World!"
  end
end

foobar = []
foobar.extend(Foo)
foobar.singleton_methods # => ["foo"]

or

foobar = []

class << foobar
  def foo
    "Hello World!"
  end
end

foobar.singleton_methods # => ["foo"]

Ruby classes are actually objects instantiated from the Class class. Their names are constants that point to this object instantiated from the Class class. While this object holds the instance methods for objects instantiated from it, its so-called class methods are kept on a singleton class.

在 ruby 中,直接對一個 object(e.g. from Array.new) 定義 method 的時候,

  1. ruby 就會從 Array 繼承一個 anonymous class 
  2. 將你定義的 method 寫在 anonymous class 裡面 
  3. 然後將 object 的 class 換成 anonymous class

此時,這個 anonymous class 就是一個 singleton class。
但是從外部是看不到的,會認為 object 是一個 class Array 的東西。

所有在 singleton class 中的 methods 就叫做 singleton methods。

實際上 ruby 只有 instance methods,所有的 class methods 都是 singleton class (between class and Class) 的 singleton methods。

singleton methods 在現實中會用的情形之一就是 test mocking。

 

由這個機制延伸來理解 Object#extend首先了解 extend 與 include 的基本用途後,

會看到 extend (新增 methods 到目前 "instance")的用法是:

 

obj = Object.new
obj.extend InstanceMethods
puts obj.an_instance_method      # >> You called an_instance_method on Object

 

在 irb 中自己打一遍,就能發現,所有被 extend 加入的 methods 都會顯示在 obj.singleton_methods 中。

也就是說,對 obj 作 extend 的意思與最上面的「直接對 object 再定義 methods 」的最後結果是一樣的!

都是產生一個 singleton class,把加入的 method 都放到 class 裡面變成 singleton_methods。

 

如果是寫成這樣:

class MyClass
  include InstanceMethods
  extend ClassMethods
end

在這裡的 extend ClassMethods 與 MyClass.new.extend(ClassMethods) 是一樣的意思,能直接寫在 class 定義裡面是因為 class 繼承自 Object,而 Object#extend

也就是說,與上面一樣,就是產生 singleton methods,

因為這裡的對象是 class MyClass,這些 singleton methods 也就是所謂 MyClass 的 class methods。

所以這行就是定義 class methods。

有了這個觀察到的現象,就不難理解這樣的 code:

module Rake  include Test::Unit::Assertions  def run_tests # etc.  end  # what does the next line do?  extend selfend

在這裡的 extend selfRake.new.extend(Rake) 是一樣的意思,

Rake.new.extend(Rake) 的結果就是產生了一個 singleton class,裡面的 methods 都是自己原來的 singleton methods。

也就是說,這行就是直接跟 ruby 說,我在這個 module Rake 裡面定義的所有 method 就是我的 module method(class method of class Module)。

→→→終極簡寫法。

ruby - Meaning of the word yield - Stack Overflow

The word yield doesn't really have any special meaning in the context of Ruby. It means the same thing as it means in every other programming language, or in programming and computer science in general.

It is usually used when some kind of execution context surrenders control flow to a different execution context. For example, in Unix, there is a sched_yield function which a thread can use to give up the CPU to another thread (or process). With coroutines, the term yield is generally used to transfer control from one coroutine to another. In C#, there is a yield keyword, which is used by an iterator method to give up control to the iterating method.

And in fact, this last usage is exactly identical to the usage of the Enumerator::Yielder#yield method in Ruby, which you were asking about. Calling this method will suspend the enumerator and give up control to the enumerating method.

Example:

...

As you see, there is an infinite loop. Obviously, if this loop just ran on its own, it wouldn't be of much use. But since every time it hits the yield method, it gives up control until it is called again, this will produce the Fibonacci numbers one by one, essentially representing an infinitely long list of all Fibonacci numbers.

There is another method, Fiber.yield, which serves a similar purpose. (In fact, I already described it above, because Fiber is just Ruby's name for coroutines.) Inside a Fiber, you call Fiber.yield to give up control back to the execution context that originally gave control to you.

Lastly, there is the yield keyword, which is used inside a method body to give up control to the block that was passed into the method.

Note that, at least in the Enumerator case (i.e. the first example), you can additionally interpret yield as to produce, since the Enumerator produces a new value, every time it calls yield.

解釋 yield 這個字的意思,以及在 ruby 中的 Fiber#yield 與 關鍵字yield 的差別:

Fiber#yield →將「控制權」還給之前「放控制權給你的fiber」。
yield→將「控制權」交給「傳入的block」。(也就是 callback)

[ruby-talk:14594] Re: Module method definition question

Assuming you meant 'module A', the first defines an instance method, the second a module method. The instance method cannot be called until the module is mixed in to a class using 'include'. The module method can be called by giving the module name as a receiver:

instance method 只有在被 mixed 的時候才有用

Dynamic WEBRick Servers in Ruby - igvita.com

A quick browse through the servlet examples, along with the RDoc gets us well on the way. We will start our server on port 8000, and mount two 'paths' - one for serving the survey, and second for processing the POST request (saving the form):

> webrick-init.rb

require 'rubygems'
require 'webrick'
require 'dbi'
 
# Initialize our WEBrick server
if $0 == __FILE__ then
  server = WEBrick::HTTPServer.new(:Port => 8000)
  server.mount "/questions", WebForm
  server.mount "/save", PersistAnswers
  trap "INT" do server.shutdown end
  server.start
end