zoukankan      html  css  js  c++  java
  • 3-20 标准库:find库; 学习编程语言3节课(大多是旧识,全*栈)3-21 面向对象. Percent Strings; 元编程和Rails的相互理解

    Find

    The Find module supports the top-down traversal of a set of file paths.(一系列文件的路径的遍历)

    find(*paths, ignore_error: true)
    prune()

     

    require 'find'
    IGNORE = [/^./, /^.svn$/, /^.git$/]
    def listdir(top)
      Find.find(top) do |path|
        if FileTest.directory?(path)
          dir, base = File.split(path)
          IGNORE.each do |re|
            if re =~ base
              Find.prune
            end
          end
          puts path
        end
      end
    end
    listdir("ARGV[0]")

    我直接输入目录名字,老是说没有这个目录,文件。? 

     


    Enumerable#reduce 

    reduce(initial) { |memo, obj| block } → obj
    reduce { |memo, obj| block } → obj

     reduce 的第一个参数 initial 是初始值,然后这个匿名函式依序走访容器,两个参数 memo 跟 obj,前者 memo 是前一次循环的回传结果。obj 是这次走访的元素。

     例子:reduce

    (1..3).inject { |sum, n| sum + n } 


    private 和 protected 有什么差别?

     http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby

     implict [ɪm'plɪsɪt]suggested or understood without being stated directly

     an implicit receiver of self. 隐含的自己

    private只能被an implicit receiver of self调用。obj调用一个public方法,并在这个public方法内部调用private方法,不要加self.

    protected只可以被 receiver is self的对象调用。obj调用一个public方法,并在这个方法内调用protected方法,加不加self关键字都可以。

    class Foo
      def a; end
      # call 'a' with explicit 'self' as receiver
      def b; self.a; end
      # call 'a' with implicit 'self' as receiver
      def c; a; end
    end
    def safe_send(receiver, method, message)
      # can't use 'send' because it bypasses visibility rules
      eval "receiver.#{method}"
    rescue => e
      puts "#{message}: #{e}"
    else
      puts "#{message}: succeeded"
    end
    visibility = ARGV.shift || "public"
    Foo.send(visibility, :a)
    foo = Foo.new
    safe_send(foo, :a, "explicit receiver       ")
    safe_send(foo, :b, "explicit 'self' receiver")
    safe_send(foo, :c, "implicit 'self' receiver")

    module 命名空间

     pasting

    module A
    class B
    end
    end

    这个被 module A 包起来的 class B,如果要使用它要用 A::B

    如果 module A 已经定义过了,则可以这样写:

    class A::C 
    end

    假如在 module A 里面定义了一个跟最外层撞名的类,这时候如果要拿外层的类,需要加上 :: 符号:

    class Person 
    end 
    module A 
     class Person 
     def foo 
     Person # 这个会是指 A::Person 
     ::Person  # 前面要加 :: 表示要拿最外层的 Person 
     end 
     end 
    end

    模块也是类,所以可以有模块方法(类方法),写法一样。


    名词释疑:方法的「接口(Interface)」指的是方法的名称和参数,方法的「实作(Implement)」指的是方法内实际要做的代

    面向对象的3个特点:

    1.封装。方法的使用,只需知道接口,就可以用了,方法的实做不需要了解。

    2.继承。父类定义的方法可以被子类继承。Ruby只支持单一继承,但可以使用模块混入。

    3.多态。指不同形态的东西,有共同的特点,就当初同一类东西使用。

    例子:

    Strategy Pattern 范例:情境是我们想要设计一个通用的数据输出功能,并且允许我们随时可以抽换不同的输出方式,例如 XML 或 JSON。

    思路:一个数据有格式和内容。内容不变,格式根据需要改变。

    第一,定义一个数据存储类,存储data和formatter两个属性。

    第二,定义2个格式类,每个类有不同的输出格式,但调用方法接口都是output(data)

    第三,在数据存储类中定义output, 内容是根据格式不同调用各自的方法output.

    第四,在实例化一个数据存储类时,格式属性使用格式类.new生成一个格式类的对象。 

    class AwesomeFormatter
    attr_accessor :data, :formatter
    def initialize(data, formatter)
    @data = data
    @formatter = formatter
    end
    def output
    puts self.formatter.output( self.data )
    end
    end
    class XMLFormatter
    def output(data)
    "<data>#{data}</data>"
    end
    end
    class JSONFormatter
    def output(data)
    "{ data: #{data} }"
    end
    end
    formatter = AwesomeFormatter.new( "ihower", XMLFormatter.new )
    formatter.output() # 输出 XML 格式 <data>ihower</data>
    formatter.formatter = JSONFormatter.new # 动态更换不同的输出策略
    formatter.output() # 输出 JSON 格式 { data: ihower }

    参考


    Percent Strings

      %()   string

      %w() Array of string,例子 %w(1 2) => ["1", "2"]

      %r() 正则表达式
     


     元编程: define_method


    class A
    def self.define_my_method(x)
    define_method("output_#{x}") do
    puts "This is #{x}"
    end
    end
    end
    class B < A
     define_my_method :foo # 定义 output_foo 方法
    end
    class C < A
    self.define_my_method(:bar) # 完整的写法,类宏
    end
    B.new.output_foo # 输出 This is foo
    C.new.output_bar # 输出 This is bar
     
    在定义子类时,子类调用父类的类方法,生成了一个实例方法。

    在 Rails 很多这样的宣告背后,都是用 define_method 做出来的:

    class Firm < ActiveRecord::Base
    has_many :clients
    has_one :account
    belongs_to :user
    end
    # has_many 是 AciveRecord 的类方法(class method)
    
    # 其内容是动态定义出 Firm 的一堆对象方法(instance methods)
    
    firm = Firm.find(1)
    firm.clients
    firm.account
    firm.user

    猴子补丁

    直接复写 Class 的定义去修改行为,在 Rails 中常用这招来扩增原本 Ruby 的行为,例如:

    blank? 方法检查对象是否是nil或者空字符串,空数组。 

    class Object # 在 Ruby 中所有的类都会继承自 Object 这个类
      def blank?
        respond_to?(:empty?) ? empty? : !self
      end
    end
    [1,2,3].blank? # false 
    "blah".blank? # false 
    "".blank? # true
    nil.blank? # true

     解释:Object#respond_to? (:symbol)是看receiver是否对method回应,返回boolean. 数组和字符串都有empty?方法. nil是个伪变量,没有方法。它的!self就是true

  • 相关阅读:
    一个表对应另一个表中多个主键的查询方法(把一个表当成两个表用)
    可以切换数据库的SqlHelper
    win7安装后的用户选择
    如何删除 Windows.old 文件夹
    Windows Server 2008磁盘清理工具
    sqlserver express版PRIMARY 大小不能超过4G
    一交换机,一光猫、一路由器组internet网的方法
    公司部门职责清晰
    IIS下载EXE(拾遗)
    win2008 IIS 7.0中WebDAV
  • 原文地址:https://www.cnblogs.com/chentianwei/p/8607894.html
Copyright © 2011-2022 走看看