• vagrant 的 box 跟你启动的 VM 好比类跟实例的关系。你新项目的 VM 跟你以前的 VM 是同一个 box 类的两个实例,所以你第一个 VM 装东西不会出现在第二个 VM 上。

  • vagrant package --output xxxx.box可以把你配置好的虚机导出来,然后用你导出来的 box 启一个 vm。

  • Callbacks 中的一些困惑 at 2014年01月28日

    attr_accessor :password相等于定义两个方法:

    def password
        @password
    end
    
    def password= p
       @password = p
    end
    

    如果用password = xxxx只是给一个局部变量赋值,self.password = xxxx才是调用第二个方法。password_salt 同理。如果单用password,那样不会有歧义,所以不需要加 self。

  • 元编程中验证的问题 at 2014年01月25日

    #3 楼 @engin123456789 顺手写了一下: 完整的 CheckAttr Module:

    module CheckAttr
        def self.included base
            base.extend ClassModule
            base.class_eval do
                def self.method_added method_name
                    if @_last_modified_method != method_name && method_name.to_s !~ /^_check_attr_/ && method_name.to_s !~ /=$/
                        @_last_modified_method = method_name
                        class_eval do
                            alias_method :"_check_attr_hacked_#{method_name}", method_name
                            define_method method_name do |*args, &blk|
                                ret = __send__(:"_check_attr_hacked_#{method_name}", *args, &blk)
                                instance_variables.each do |v| 
                                   method_name = :"#{v.to_s.gsub('@', '')}="
                                    __send__(method_name, instance_variable_get(v)) if respond_to? method_name
                                end
                                return ret
                            end
                        end
                    end
                end
            end
        end
    
        class InvalidAttributeError < Exception; end
    
        module ClassModule
            def attr_checked attr, &validate_block
                define_method "#{attr}=" do |value|
                    raise InvalidAttributeError.new("@#{attr}") unless validate_block.call value
                    instance_variable_set "@#{attr}",value
                end
    
                define_method attr do
                    instance_variable_get "@#{attr}"
                end
            end
        end
    
    
    end
    

    Usage:

    class Person
        include CheckAttr
        attr_checked :age do |v|
            v >= 18
        end
        attr_checked(:weight) {|v| v >= 40}
        def initialize name,age, weight
            @name = name
            @age = age
            @weight = weight
        end
    
        def lose_weight w
            @weight -= w
        end
    end
    
    #person1 = Person.new 'shiyj',16, 50 # raise: InvalidAttributeError: @age
    person2 = Person.new 'Fat Guy', 35, 200
    person2.lose_weight 180 # raise InvalidAttributeError: @weight
    

    大体就这思路,你可以再调整一下。 又或者你改一下你的思路,做成显示的验证,比如在执行 save 一类的时候验证,会方便高效许多。

  • 元编程中验证的问题 at 2014年01月25日

    #3 楼 @engin123456789 每个方法都加一遍验证一点都不过,我上面的代码稍微改动一下就行了,用 method_added 的钩子,自动 hack 每一个新加的方法,完成一遍验证。

  • 元编程中验证的问题 at 2014年01月23日

    不知道有没有@age=的时候能触发的 hook,不过根据你的需求可以实现在 initialize 的时候验证

    module CheckAttr
        def self.included base
            base.extend ClassModule
    
            base.class_eval do 
                def self.method_added method_name
                    if method_name == :initialize && !@_mark_
                        class_eval do
                            alias_method :original_initialize, :initialize
                            @_mark_ = true
    
                            def initialize *args, &blk
                                original_initialize *args, &blk
                                instance_variables.each do |v| 
                                   method_name = :"#{v.to_s.gsub('@', '')}="
                                    __send__(method_name, instance_variable_get(v)) if respond_to? method_name
                                end
                            end                        
                        end
                    end
                end
    
            end
    
        end
    
  • 准确的说应该是&会调用后面的东西的 to_proc 方法。

  • &:upcase 等于:upcase.to_proc,可以参考一下 Symbol#to_proc

  • proc 中的 return at 2014年01月06日

    #8 楼 @u1378130755 这段代码跟p = Proc.new { puts "hello test" ; return}等价,有什么问题么?

  • proc 中的 return at 2014年01月06日

    鼠标不好用……经常风怒

  • proc 中的 return at 2014年01月06日

    #3 楼 @u1378130755 p.call 是在这个 block 的作用域里执行 block 里面的代码,p 的作用域跟 test1 方法的作用域相同,所以里面的 return 跟在方法里 return 一样的。

  • proc 中的 return at 2014年01月06日

    #3 楼 @u1378130755 p.call 是在这个 block 的作用域里执行 block 里面的代码,p 的作用域跟 test1 方法的作用域相同,所以里面的 return 跟在方法里 return 一样的。

  • proc 中的 return at 2014年01月06日

    #3 楼 @u1378130755 这只是建了一个 Proc 对象,没执行 return,直到 call 了才会执行。

  • proc 中的 return at 2014年01月06日

    要用 block 里返回值要用 next,不是 return。

  • def generate_table operator
        1.upto(9) do |i|
            i.upto(9) {|j| print "#{i} #{operator} #{j} = #{i.send(operator, j)}\t"}
            print "\n"
        end
    end
    
    generate_table :+
    generate_table :-
    generate_table :*
    
  • :"xxx"相当于"xxx".to_sym,就像&:+相当于:+.to_proc

  • #4 楼 @fbsender 这里面的@@a是属于顶层Object类的类变量只是现象,不知道是什么原因。

    class A
        @@a = "It is @@a"
        def get_a
            puts @@a
        end
    end
    
    obj = A.new
    
    obj.get_a
    
    obj.singleton_class.class_eval do
        # 如果这里相当于Object.class_eval的话,为什么下面的get_a_singleton只属于obj?
        @@a = 1
    
        def get_a_singleton
            puts @@a
        end
    
    end
    
    obj.get_a_singleton
    

    不过 singleton_class 作为一个只有一个实例匿名的类想不出 class variable 能有什么作用,所以从使用的角度来说这种场景应该不会出现。

  • 因为前面的 @@a 是 class A 的类变量,class << obj 里面的 @@a 是 obj 的 singleton class 里的 @@a,加上

    obj.singleton_class.class_eval do
        @@a = 1
    end
    

    这个 @@a 才是 obj.get_a_singleton 能读到的 @@a

  • 只学 ruby 的话很简单。要学 ror 的话,纯 ruby 的只是能占 40% 么……

  • ETL 工具都带这些功能吧

  • #4 楼 @suupic 刚刚知道是什么 csv……

  • records = []
    
    File.open('xxx.csv') do |f|
        first_line = true   
        f.each_line do |line|
            if first_line
                @headers = line.chomp.split(',')
                first_line = false
            else
                record = {}
                line.chomp.split(',').each_with_index do |value, idx|
                    record[@headers[idx]] = value
                end
                records << record
            end
        end
    end
    
    # 白菜名
    records.group_by {|record| record["Name"]}.each do |name, _records| 
        if @max.to_i < _records.size 
            @max = _records.size
            @baicai_name = name
        end
    end
    
    p @baicai_name, @max
    
    # 邮箱后缀
    @max = 0
    records.group_by {|record| record["EMail"][/@.*$/]}.each do |email_suffix, _records| 
        if @max.to_i < _records.size 
            @max = _records.size
            @baicai_email_suffix = email_suffix
        end
    end
    
    p @baicai_email_suffix, @max
    ```ruby
    
  • 你开网页有没有加代理。

  • eigenclass 和 Module 的问题 at 2013年09月19日

    #11 楼 @woody1983 你是说 extend 么

  • 输出和预想的不一样呢 at 2013年09月18日

    x = Thread.new { sleep 0.1; print "x"; print "y"; print "z" } a = Thread.new { print "a"; print "b"; sleep 0.2; print "c" } sleep 1