美文网首页
读《松本行弘的程序世界》

读《松本行弘的程序世界》

作者: orcl_zhang | 来源:发表于2015-07-29 08:07 被阅读41次

断断续续花了很久才把这本书读完,内容比较杂,也不是特别深入,应该是从日常的文章汇总而成,有些内容还是值得一读。而且可以看出作者并没有仔细的整理这些内容,关于对象和块的章节重复和累赘部分很多,关于 Schewarzian Transform 也讲了很多次。

1 我为什么开发 Ruby

  • 语言可以影响说话者的思想;
  • 一个程序员不管他使用什么编程语言,他在一定时间里编写的程序行数是一定的。

2 面向对象

  • 引入有限制的多重继承应该是一个好方法。
  • 与继承有关的内容。
用语 内容
单一继承 只有一个父类,单纯但存在几个问题
多重继承 多个父类,但引入了单一继承没有的新问题
静态语言(Java) 区分规格继承和实现继承
动态语言 只有实现继承
规格多重继承的问题 Java 的接口可以解决
实现多重继承的问题 Mix-in 可以解决
Mix-in 所有支持多重继承的语言都可以考虑使用
Ruby 的 Mix-in 强制使用模块,来解决多重继承的问题
  • 静态语言中可以实现多态性的只是限于拥有共通父类的对象。
  • 数据要记录与自己数据类型有关的信息。这样的数据类型称为动态类型。
  • 静态类型,直接执行,速度快。
  • 动态类型,边解释源代码边执行速度慢。优点,灵活性。

3 程序块

  • C 语言是通过函数指针来把函数作为一种对象来处理的。
  • 在块中可以引用外部局部变量的方法,说明块不知是简单的程序代码,而且把外部“环境”也包括了进来,想这样的块称为闭包。
  • 在被调用的方法中有两种方式来使用传递来的块。一种是用“块参数”的方式明确声明接受块作为参数,另一种是使用yield这个Ruby的保留词。
def each(&block)
  i = 0
  while i < self.size
    block.call(self[i])
    i+=1
  end
end
def each()
  i=0
  while i < self.size
    yield self[i]
    i+=1
  end
end

块作为参数的优点:

  1. 明确表示了块处理;
  2. 块和对象一样被统一处理了;
  3. 检查参数是否为 nil 就可以判断是否传递了块参数。

yield 的优点:

  1. 没有用到闭包,执行速度稍快;
  2. 错误信息比较用一理解。
  • sort_by 用执行的代码块生成的结果拍续,对每个元素只执行一次块的调用。与其说是比较两个元素,更多的时候是对每个元素进行某种处理,用处理的结果来排序。(原来如此)。
  • 用块来保证程序的后处理。

3.2.5 Enumerable 的局限(赞)

Enumerable 的两个主要缺点:

  1. 循环都依赖 each 方法,而且不能并行执行;
  2. 从多个对象取出元素进行处理比较难写。

用 Ruby 来定义 zip 方法的话,到目前为止,因为没有提供外部迭代器,所以只能在内部把参数变换成数组来对应。把参数作成数组,有以下两个问题:

  1. 大量的数据变换成数组会造成资源的浪费;
  2. 不能处理无限循环的 Enumerable。

代码部分:

module Enumerable
  def zip(*args)
    n = 0
    args = args.map{|a| a.to_a }
    self.each do |x|
      yield [x, *args.map{|a| a[n] }]
      n += 1
    end
  end
end

可以修改为:

module Enumerable
  def zip(*args)
    args = args.map{|a| a.enum_for(:each) }
    self.each do |x|
      yield [x, *args.map{|a|
        a.next rescue nil
      }]
     end
   end
end
  1. 不要变换成数组,而是用 enum_for 方法变换成以 each 为基础的 Enumerator。如果是 Ruby 1.8.7 ,这部分可以通过调用块的 each 方法来实现,但是如果这个类没有 each 方法,可能不返回 Enumerator。所以用 enum_for 方法才是安全的。
  2. 如果参数用数组可能会消耗很大内存。

4 设计模式

  • 设计模式的本质,并不是介绍至今没有用过的新模式,而是通过给屡屡使用过的模式起一个合适的名字,从而提供了设计时的词汇。
  • 旧约全书里记载了巴比伦塔的故事,描写了人与人之间因为语言不通,而中止了塔的建设,人们纷纷散去的场面。语言的重要性可见一斑。(沟通的重要性)。

5 Ajax (建议粗读,内容有点老,而且也比较浅)

6 Ruby on Rails

6.2.3 猴子补丁技巧

** undef **
undef 有把方法定义取消的功能。用 undef 不仅可以取消本类中的方法,也可以取消父类中的方法。
** remove_method **
remove_method 仅取消本类中的方法。
alias
用 undef 或 remove_method 删除了以前方法后,别名的方法依然可以使用。别以 alias 只是起别名,而是重新定义了一个方法。

7 文字编码(不感兴趣可以跳过)

文字编码的难度还是很大的。

正则表达式(赞)(要比Ruby镐头书和元编程介绍的详细)

锚点 匹配位置
^ 行首
$ 行尾(若含换行,则是其前面的字符)
\A 字符串头
\Z 字符串尾(若含换行,匹配前一字符)
\z 字符串尾
\b 词头或词尾([] 外)
(?=) 用模式指定位置
(?!) 用否定模式制定位置

*贪婪与懒惰 **
这是一个经常讨论的问题,记得加 .

分组
使用向后引用的时候,因为要在内部保存数据,效率会受影响。如果仅仅为了分组,而不需要使用向后引用,可以使用没有向后饮用的模式括号(?:)。
锚点

锚点 匹配位置
^ 行首
$ 行尾(若含换行,则是其前面的字符)
\A 字符串头
\Z 字符串尾(若含换行,匹配前一字符)
\z 字符串尾
\b 词头或词尾([] 外)
(?=) 用模式指定位置
(?!) 用否定模式制定位置
选项 含义
i 不区分大小写
m 复数行匹配
o 只展开一次
x 无视正则表达式的空格,注释有效

选项

选项 含义
i 不区分大小写
m 复数行匹配
o 只展开一次
x 无视正则表达式的空格,注释有效

注释

/\d{4}-? #year
  \d{1,2}-? #month
  \d{1,2} #day
/x

8.1.7 特殊变量

$& 最后匹配字符串

8.1.9 split 的本质

  • 用固定字符串分割字符串
  • 用正则来分隔
  • 如果不想去掉标签,而是将其保存下来,可以用括号将模式包起来。
str = "<ul><li>a</li>b</ul>"
str.split(/(<.*?>)/)
# ["", "<ul>", "", "<li>", "a", "</li>", "b", "</ul>"]

8.1.10 字符串扫描

"afdasfasdfads".scan(/fa./){|s| p s }

下面代码执行同样的动作。它不生成无用的数组,效率稍高一点。(谁能告诉我为什么?)

"afdasfasdfads".scan(/fa./).each{|s| p s }

8.1.11 置换

置换字符串

a = 'abbbcd'
a.gsub(/a(b+)/, "#{$1}") #wrong
a.gsub(/a(b+)/, "\1") #wrong
a.gsub(/a(b+)/, "\\1") #right
a.gsub(/a(b+)/, '\1') #right
a.gsub(/a(b+)/, '\\1') #right
a.gsub(/a(b+)/){ $1 } #right

居然'\1'和'\1'都可以!

相关文章

网友评论

      本文标题:读《松本行弘的程序世界》

      本文链接:https://www.haomeiwen.com/subject/odimqttx.html