• 你们公司内部肯定是属于沟通密集型。而社区比较松散吧。 这个我想没什么规律吧。 还没听说有多少公司统计这个的。

  • #54 楼 @luikore 恩,同意你说的这个坑。

    其实,我说的就是,在 Ruby 里,你随便混入,他们都在一个继承树上,不会乱。 而你是提醒了别人,组合的时候注意载入顺序,或者使用定义可读的方法名来避免把程序员自己搞混。

    「增加:」所以,我说的‘实质’就是,不管你怎么组合,他们都挂在一个继承树上。

    剩下的,就看大家怎么去理解了。

  • 哈哈,今天我也发了个重复的老帖子

  • #51 楼 @luikore 关键不在“实质”,可能咱俩对于“多重继承”在 Ruby 里的概念不同所致。Matz 实现的是,继承关系单一,又可以共用方法的多重继承。你可能用了 C++ 多重继承来理解我说的这个多重继承,所以你有菱形问题这么一说。

  • #51 楼 @luikore 是实质。你看 50 楼我留言吧。

  • @luikore 再补充一点:你在楼上举的那个例子,所谓的菱形问题,是个伪问题,Ruby 里根本不存在这样的问题。

    多重继承是描述类之间的关系,而组合,描述的是对象之间的关系,当然,如果你只从方法集合这个层面来说,Mix-in 是一种组合方式,也能说的通。

    继承是 is_a,组合是 has_a, 你把 Module 理解为一个方法集合,当然是组合了,这个类 include 了 module,它的对象就可以 has_a 这个方法,has_a 那个方法。

    而且 Module 本身是 Class 的父类, Class.superclass #=> Module

    include 也是在 Module 中被定义的私有方法,如果你 include 一个模块,那么会把这个模块加到这个类的继承树里,请问用组合的概念如何解释这一行为?

    所以得出的结论是,如果你只把 Mix-in 当作一个方法集合,而不关注类和模块的关系,那可以理解为组合,但这只是表面,当然理解到这一层,不影响编写代码了。但可能会碰到奇怪的问题,比如你举的那种菱形问题,会让你迷惑。

    真正理解了 Mix-in 是多重继承(不是传统的多重继承,继承关系是单一的,又有多重继承的共用方法,不要用 C++ 那种多重继承去理解)这个概念, 「你说的:编程时不好确定调用到哪里」,这种问题也不会存在了。

  • #13 楼 @luikore 是这样的。可能是我看着别扭吧。 😏

  • 关于这个问题,我不继续讨论了。毕竟每个人有每个人的理解,我只是传达了 Matz 在他书里的论述。大家能怎么理解就怎么理解吧。☺

  • #46 楼 @luikore 本来就是继承嘛,为什么要避免呢, 《松本行弘的程序世界》31 页里面 Matz 解释的很清楚嘛。或者说,Mix-in 是 Ruby 里实现多重继承的方式,而且通过 Mix-in 这种方式,降低了传统多重继承的复杂性,更进一步说,Mix-in 是经过 Matz 改良的 Ruby 里实现多重继承的方式。

    你说 35 页里写:多重继承相当于语言功能支持模块组合。

    原文里还有前面一句话,假如把类当模块来看的话。而且,那句话的章节标题就是:动态编程语言也需要多重继承。

    现在是模块是类,Mix-in 模块算是一种抽象类。它只是有限制,都是 Class 类的子类。

    Matz 那本书里第二章基本通篇在说继承和多重继承与 Mix-in 的。

    我为什么要和你讨论呢,就是因为你说「Mix-in 不是继承」,可它明明就是继承,你为什么要避免增加它外延,我也没有增加其外延,我说的就是多重继承,多重继承不也是一种继承嘛。Ruby 里的继承一般是指类和类之间的关系,而类和多个模块的时候,就是 Mix-in,多重继承。

    所以我说,Mix-in 的实质是多重继承的一个实现方式。这就是讨论的意义所在。😄

    你说的这句,[我说的是编程时不好确定调用到哪里,你说的是运行时这个东西是确定的] ,我也认同,楼上就认同了,我说你阐述的是一种编程方法,但是你用编程方法来理解 Mix-in 的工作原理实现方式,我就不认同了。

    而且,matz 也说了,继承就是利用模块的方法(34 页)。

    我说 Mix-in 是一种继承,你说继承是一种组合方式。

  • #11 楼 @luikore 你不觉得影响了可读性吗

  • #42 楼 @luikore 是的,载入顺序影响了 ancestors 的继承树。这样讲也行。但对我来说,理解为多重继承要比组合更为清晰。看大家怎么理解了。

  • #41 楼 @sevk 那是类实例变量

  • http://ruby-china.org/topics/11249

    这也有个评测,你可以看看。 说明的是 Goliath 不用 Grape 也可以。

  • #2 楼 @shell 嗯,异步。你可以去了解一下: https://github.com/postrank-labs/goliath

  • 推荐 Goliath

  • #39 楼 @simlegate 多看几遍吧,尤其是前几章讲他设计 Ruby 的过程。这本书不是教你 Ruby 语法的。比如第 30 页和 31 页,你就可以看到 Mix-in 和多重继承的关系,引导你解决一些问题。你就不会在 module 和 class 的关系上感到迷惑了。「原文:对 Mix-in 的理解是,Mix-in 只不过是实现多重继承的一个技巧而已。Ruby 只支持 Mix-in 形式的多重继承。Matz 也说了,曾有一个著名的青年学者因为 Ruby 的原因而误认为多重继承和 Mix-in 是不同的概念,这个让 Matz 有点惭愧,他觉得这些误解部分是他造成的,哈哈。」

    还有很多地方: 「Mix-in 是使类结构变的简单的优秀技术。Mix-in 使多重继承的类形成非常清晰的树结构,没有变成网状结构。」如果非要使用组合的概念去理解 Mix-in,正好和 Matz 设计 Mix-in 的初衷相悖,让 Matz 情以何堪。

  • #37 楼 @simlegate 因为 Ruby 太灵活了啊,如果不把握一些实质,很容易被 Ruby 搞晕。所以我推荐去看 Matz 的书,看他设计 Ruby 的初衷和原则,对于我们理解 Ruby 里面的概念很有帮助。这可比看源码实际多了。

  • #35 楼 @nickelchen 去看 Matz 的《松本行弘的程序世界》一书吧,从 Matz 如何设计 Ruby 里面可以看出,Mix-in 正好解决了传统的多继承的问题,降低了复杂性,就像我楼上说的,Matz 设计 Mix-in 的这种机制,就是为了让程序员可以像单继承那样去使用多继承。所以不要和 C++ 的多继承去比,如果一定要比,Ruby 的实现和 Java 的更类似。

    只有理解了这个实质,写代码的时候才不容易被 Mix-in 搞晕啊。

  • #33 楼 @kewin 我应该比你早一段时间,当年面我那个 CTO 据说已经离开了团 800 了。现在估计团 800 也不只是做团购啊。

  • #33 楼 @alan90121 嗯。刚开始 simlegate 打错字了,实例方法打成了实例变量,所以我看着有点奇怪。 😄

  • 在 Ruby 里面,很大的数字被存储为 Bignum 对象,实在要研究,你可以看看 Bignum 的源码。

  • 一个 Ruby 笔试题 at July 26, 2013

    #20 楼 @goinaction 好吧,我想也不应该是 bug,否则在 Ruby2.0 里应该被改了。以后使用的时候需要小心。

  • yield 关键字的使用 at July 26, 2013

    @Msms 晕了。 yield 的作用是「转让」块代码,块代码可以看做是一个匿名函数。记住这一条原则就可以了。Ruby 灵活多变,我们需要抓住一条不变的实质,才能处理一些问题。否则的话,看在眼里都是奇怪的结果。

    test_yield("locale", ["name","desc"], "locale") do |arr, locale|
        puts arr.class.to_s  
        puts arr.to_s
    end
    
    

    相当于

    
    def test_yield (select_locale,value,locale)
    
          #经过yield,把块代码压入方法堆栈
          f(arr, locale){ 
              puts arr.class.to_s
              puts arr.to_s
         } 
    

    yield value 这里 yield 后面的参数就是传递给块那个匿名方法参数的。所以要注意参数个数(块里的参数)。

    @ihlayy 总结的也很好,只是感觉没说到点子上。

  • 一个 Ruby 笔试题 at July 26, 2013

    果然是坑。这应该算 bug 吧。

  • 嗯,很不错。资料有点旧了,但不影响学习。

  • 请教个 ruby 问题? at July 26, 2013

    一个对象,可以理解为类和实例对象,本身类也算是 Class 的一个实例对象。 单例方法,如果是类的单例方法,那就是类方法,你想在另一个类里调用这个类的类方法,可以这样。

    class A
      def self.test
        puts "hello"
      end
    end
    
    class B
      def self.test
        A.test
      end
    end
    

    如果是实例对象。

    module A
      def test
         "hello"
      end
    end
    
    class B;end
    class C;end
    
    b = B.new
    c = C.new
    b.extend A
    c.extend A
    
    b.test
    c.test
    

    实例对象的单例方法,你无法在另一个对象中直接调用,因为在另一个对象中找不到那个方法,只会把它当实例变量去处理。