• 量产型炮灰工程师 at 2017年5月22日

    http://threeifbywhiskey.github.io/2014/03/05/non-alphanumeric-ruby-for-fun-and-not-much-else/

    _=$$/$$;__=_-_;@_=_+_;$_=@_+_;$__=@_+$_;$-_=$__*$_;@__=''<<$-_*($__+$_)+@_;$___=''<<$-_*$__-$__<<$-_*($__+@_)<<@__<<@__;@___=''<<$-_*$__-$_*$_<<$-_*($__+$_)-$_<<@__<<@__;(___=->{$.+=_;$><<($.%$-_==__ ?$___+@___:$.%$_==__ ?$___:$.%$__==__ ?@___:$.)<<(''<<$__*@_);$.<($__*@_)**@_?___[]:_})[]
    
  • mysql index自动选择的问题,常见的坑,可以在查询里面加FORCE INDEX来解决

  • 对于这种需求,我推荐Decorator模式,有现成的gem draper可以用

    https://github.com/drapergem/draper

  • 因为我要想在用户注册之后,加入更多逻辑的话

    比如要加一个FooBar的逻辑,你的做法是在 config/initializer/business.rb 加一行:

    Fanli.on(:create_user, [
      SendWelcomeEmail,
      GiveCouponIfXmas,
      GiveInitialCash,
      FooBar,
    ])
    

    而我的做法是在CreateUser里面加一行

    [SendWelcomeEmail, GiveCouponIfXmas, GiveInitialCash, FooBar].each
    

    剩下其他代码都是一样的,你可以说你那个是配置,我那个需要修改代码,但是在这个例子里面看不出两者有什么本质区别。

    如果非要改成配置的方式,那么我们改一下代码:

    class CreateUser
      def perform(args)
        user = User.create!(args)
        callbacks(args)
      end
    
      def callbacks(args)
        callbacks_from_config.each do |clazz|
          clazz.(args)
        end
      end
    end
    

    即使抽象一个Base出来,看起来和你的例子一模一样了,但是本质上还是意大利面条:

    class Base
      def perform(args)
        _perform(args)
        callbacks(args)
      end
    end
    
    class CreateUser < Base
      def _perform(args)
        user = User.create!(args)
      end
    end
    

    所以从这个例子上我看不出有用Pub/Sub的任何优势

  • 代码结构和README里面的例子是一模一样的,例子怎么做单元测试,上面的代码也是一样做,单一职责并没有违反,做的事情都在各自代码里面,和例子也是一模一样的

  • 感觉这和直接写意大利面代码没什么区别

    class CreateUser
      def perform(args)
        user = User.create!(args)
    
        [SendWelcomeEmail, GiveCouponIfXmas, GiveInitialCash].each do |clazz|
          clazz.(args)
        end
      end
    end
    
    class SendWelcomeEmail
      def self.call(args)
      end
    end
    
    class GiveCouponIfXmas
      def self.call(args)
      end
    end
    
    class GiveInitialCash
      def self.call(args)
      end
    end
    
  • Map for hash array using &: at 2017年4月30日

    &后面跟的是Symbol,我们可以给它加个monkey patch

    class Symbol
      def call(*args, &block)
        ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
      end
    end
    

    然后call在Ruby里面有.()的便捷调用,就可以这样写了:

    a = [{aa: '123'}, {aa: '321'}]
    
    a.map &:[].(:aa)
    

    忘记在哪里看到这个技巧的,但是真的很好用

    [%w(hello world), %w(ruby on rails), %w(foo bar)].map(&:inject.(&:+))
    
  • nginx设置一下,其他域名访问重定向到ruby-china.org,就可以了,管局只看在浏览器里面输入域名,然后看返回的是什么

  • 在Java里面很流行的做法,用annotation做AOP,ruby有一些gem可以让你很方便写,比如 https://github.com/comparaonline/co_aspects

    你需要自己写一个Aspect:

    module CoAspects
      module Aspects
        class CacheAspect < Aspector::Base
          around method_arg: true do |method, proxy, *args, &block|
            cache_key = [self.class, method].join('.') + ':' + args.join(',')
            Cache.fetch cache_key do
              proxy.call(*args, &block)
            end
          end
        end
      end
    end
    

    用到这个Aspect的地方,写一个annotation(伪)就可以了:

    class Foo
      aspects_annotations!
    
      _cache
      def bar
        'bar'
      end
    end
    
  • 数据库开slow query log,5.7还是慢可能和查询语句有关,把log到的语句explain一下看看

Ruby程序猿,写OC的果黑程序猿,蝉游记2号保管猿