LJZN

每天更新Rails练习项目到Github~

» Home
» Category
» About Me
» Github

(Why的Ruby书)第三章-希望这是有趣的

02 Jan 2016 » why

Why the Lucky Stiff

1.我们谈论的是语言

我不想把Ruby称作是一门计算机语言。那意味着它主要运作在计算机上。意味着这门语言首先是为适应计算机而设计的。然后,我们这些程序员,作为计算机世界里的外国人,向真实世界翻译着计算机的语言。

但是,当你用这门语言思考时大脑在想什么?当我们可以用语言中的单词和口语来表达自己,计算机能做到吗?不能。所以为什么把它称作计算机语言,这是人类的语言!

我们不再用程序员的术语,称它为计算机语言了。事实上,它是一门思想的语言。

大声读下面的话

5.times { print "Odelay!" }

在英语句子里,标点符号是不发音的。它们起到辅助解释句子的作用。所以我们这样读:五次打印“Odealy!”.

这就是小Ruby做的事情,在电脑屏幕上打印了五次这句话。

大声读下面的话

exit unless "restaurant".include? "aura"

我们的程序会退出,除非单词“餐厅”里有“光环”。再次用英语来说:退出除非餐厅里有光环。

曾有过编程语言如此有效地使用问号吗?Ruby使用问号之类的符号来增加代码的可读性。我们正用上面的代码提出一个问题,所以为什么不明显些呢?

大声读下面的话

['toast', 'cheese', 'wine'].each { |food| print food.capitalize  }

虽然和上面几句比起来可读性要低一点,但也能看作是简短的英语。用完整的英语读出来就是:单词”toast”,”cheese”,还有”wine”:拿出每个食物让后打印它以首字母大写的格式。

计算机立刻回复:Toast,Cheese还有Wine。

这时,你可能想知道代码中的框框和符号代表什么,在后面我会提到。

现在你应该知道Ruby主要由基本的句子构成。不是准确的英语句子。它们是由单词和符号来传达思想。这些句子可以组成一本书。它们可以组成一整篇小说。人类可以读,计算机也可以读。

2.词汇分类

就像臭鼬尾巴上的白条纹,新娘的白色长裙,许多Ruby中的单词会给你一些暗示,帮助你辨认他们。符号和大写会让你的大脑产生强烈印象。你的思想不断地说:嘿,我见过这家伙!你也可以依此和其他Rubyist进行交流。

试着阅读下面给出的词类解释。本书之后的部分会详细描述它们。我给出了一些简短的解释,你不一定需要马上理解它们。到本书的最后,你会能够像Ruby程序员那样辨认每个部分。

变量

任何无符号的,小写的单词在Ruby中都是变量。变量可以由字母,数字和下划线组成。

例如x,y,banana2或phone_a_quil 都是变量。

变量就像是昵称。还记得每个人都称呼你为臭皮特吗?人们喊道:“来这儿,臭皮特!”同时大家不可思议地都知道臭皮特就是你。

你可以用变量给你经常要用的东西取个昵称。例如,让我们来运作一个孤儿院。我是说孤儿院没错。大款爸爸无论什么时候来买孩子,我们都坚持要他支付_一百二十一元又八分_来买孩子的泰迪熊,这样漫漫长夜里孩子才能抱着它安然入睡。

teddy_bear_fee = 121.08

接着,当你在Ruby中计算总费用时,你必须把所有费用加到总和里。

total = orphan_fee + teddy_bear_fee + gratuity

这些变量确实很有用。我相信在糟糕的人贩行业里,这些帮助会被感激的。

数字

最基础的数字就是整数,我们可以在开头加上正负号。

比如1, 23, 和 -10000。

逗号不允许放在数字中,但下划线可以。所以当你需要标记千位时可以用下划线。

population = 12_000_000_000

小数在Ruby中被称作浮点数。浮点数由带小数点或科学记数法的数字组成。

例如3.14, -808.08 和 12.043e-04。

字符串

字符串是引号中的任何字符(字母,数字,符号)。单引号和双引号都可以创建字符串。

例如”sealab”, ‘2021’, or “These cartoons are hilarious!” 。

当你用引号把字符包起来时,它们以单个字符串的形式存储。

想想一个记者记下名人随口说的话。“我聪明多了,”艾薇儿说,“现在我知道什么是生意————你必须去做和要知道怎么做的事。”

avril_quote = "I'm a lot wiser.  Now I know
what the business is like -- what you have
to do and how to work it."

现在我们在变量_avril_quote_中保存了一组字符串,就像刚才在变量_teddy_bear_fee_中保存数字一样。记者把这句引述交给了打印机,它专门用于打印Ruby事物。

print oprah_quote
print avril_quote
print ashlee_simpson_debacle

符号

符号看上去有点像变量。它们也可以包括字母,数字或下划线。但是符号以引号开头。

例如:a, :b, or :ponce_de_leon。

符号是轻量级的字符串。通常,符号用于替代那些你不想打印在屏幕上的字符串。

你可能会说符号更方便计算机使用。符号就像是计算机胃疼时吃的一片药,引号就是消化时冒出的泡泡。啊,多么甜蜜的比喻。

常量

常量是首字母大写的变量。如果变量是Ruby中的名词,那么常量就是专有名词。

例如Time, Array or Bunny_Lake_is_Missing。

在英语中,专有名词的首字母大写。The Empire State Building。你不能移动The Empire State Building,只能把它定义成别的什么东西。专有名词定义一些非常特别并且一般不会改变的东西。

因此,专有名词在设置后不可以改变。

EmpireStateBuilding = "350 5th Avenue, NYC, NY"

如果我们试着改变常量,Ruby会皱起眉头抱怨。

方法

如果说变量和常量是名词,那么方法就是动词。方法一般跟在变量和常量后面,以一个句号连接。你之前已经见过它了。

front_door.open

在这里,_打开_是方法。是一个动作。有时,你会看到动作连在一起。

front_door.open.close

我们让计算机打开前门然后立刻关上。

front_door.is_open?

这也是一个动作。我们让计算机测试门开了没有。这个方法可以命名为Door.test_to_see_if_its_open。但是is_open?要好得多。感叹号和问号都可以用与方法命名。

方法参数

执行一个方法有时需要更多的信息。如果我们让计算机粉刷门,我们需要给出一个颜色。

方法变量跟在方法之后,通常以括号包围,以逗号分隔。

front_door.paint( 3, :red )

给前门画上3件红色大衣。

想象一下,方法拉着一个内部管道,装着他的额外工具。括号构成了又圆又湿的管道壁。逗号是每个参数的脚,站在管道里。最后一个除外,它盘腿坐着。

像一艘船拉着许多管道,带参数的方法也可以被连起来。

front_door.paint( 3, :red ).dry( 30 ).close()

在前门上画三件件红大衣,晾干30分钟,然后关门。即使最后一个方法没有参数,你也可以加上括号。带着一个空管道是没用的,所以一般这种括号都被扔了。

一些方法是核心方法(比如print)。它们在Ruby的各处使用。因为太常用了,你都不用加句号。

print "See, no dot.

类方法

和上面提到的方法(也叫实例方法)一样,类方法通常跟在变量和常量后面。用两个引号取代句号。

Door::new( :oak )

类方法new通常用于创造一样东西。我们让Ruby为我们做一个新的木门。当然,Ruby必须明白怎么做一个门————包括名贵木材,伐木工人,和那些长长的双人锯。

全局变量

以美元符号开头的变量是全局变量。

例如$x, $1, $chunky and $CHunKY_bACOn。

大多数变量都是暂时的。你程序的一部分就像是一个小房子。你走进去发现他们有自己的变量。在一个房子里,你的爸爸可能是一个叫Archie的爱好收集骨头的旅行推销员。在另一个房子里,爸爸可能变成了爱穿法兰绒的驯狮员Perter。每个房子都有他们对爸爸的定义。

借助全局变量,你可以确保每个房子的变量都相同。美元符号非常合适。每个美国家庭都尊重美元的价值。我们对这东西非常疯狂。试着敲开一户美国人家的门,递上钞票。我敢保证你得到的反应会和递上Perer完全不同。

全局变量可以在你程序的任何地方使用,它们不会消失。

实例变量

以@符号开头的变量是实例变量。

例如@x, @y, and @only_the_chunkiest_cut_of_bacon_I_have_ever_seen。

这些变量通常用于定义一些东西的属性。比如,你可以通过在front_door里定义@width变量来向Ruby提供前门的宽度。在Ruby里实例变量一般用于定义单个物品的特性。

把_at_符号记作_attribute_的意思。

类变量

以两个@开头的变量是类变量。

例如@@x, @@y, and @@i_will_take_your_chunky_bacon_and_raise_you_two。

类变量也被用于定义属性。定义的是Ruby中许多相关的物品的属性,而不是单个物品的属性。如果实例变量定义了一个前门的属性,那么类变量就定义了作为一个门需要的所有属性。

把两个@符号记成是_attribute all_。你也可以想象一大群被Ruby控制的星球大战里的AT-ATS机器人挤在一起。当你改变其中一个的类变量时,它们全部都改变了。

由大括号包围的任何代码都是块。

2.times {
  print "Yes, I've used chunky bacon in my examples, but never again!"
}

你可以使用块把一套指令集合成一个单元以便能传送给你的程序。两个大括号像螃蟹的爪子一样抓住了代码。当你看到这两个爪子,记住里面的代码是被集合成一个单元的。

这就像商场里卖的那种Hello Kitty小盒子,其中填充着微型的纸和笔,都被包装在闪亮的透明小盒子里。你能把它藏在手里随时拿出来看。不同的是使用块不需要使劲眯着眼睛。

大括号也可以由_do_和_end_来代替,当你的块不止一行的时候很管用。

loop do
  print "Much better."
  print "Ah.  More space!"
  print "My back was killin' me in those crab pincers."
end

块参数

块参数是一组由管道符包围,以逗号分隔的变量。

例如 x , x,y , and up, down, all_around

块参数在块的开头被使用。

{ x,y x + y }
x,y 是参数。后面跟着代码。表达式x+y把这两个参数加了起来。

我喜欢把管道符当成是一条滑梯。变量从上面滑下来。(x在大鹏展翅,y则合拢了腿。)这个滑梯连接了块与外面的世界。

变量通过这个滑梯进入了块。

范围

一个范围由括号包围,以省略号隔开(两点或三点的形式)的两个值组成。

  • (1..3)是一个范围,代表数字1到3.

  • (‘a’..’z’)是一个范围,代表小写字母。

把它想象成一个为了运输而折叠起来的手风琴。(你可以运输一个没有折叠起来的手风琴,但是你会发现自己过于乐观了。)括号是手风琴的把手。句号是连接褶皱的链条。

通常只用两个点。如果有三个点,最后一个值会被排除在范围之外。

  • (0…5)代表数字0到4。

当你看见三个点,想象自己轻轻地拉开了手风琴,一页笔记掉了出来。那就是最后一个值,让它随风而去吧。

数组

数组是一个由方括号包围,以逗号分隔的列表。

  • [1,2,3]是一个数字数组

  • [‘coat’, ‘mittens’, ‘snowboard’]是一个字符串数组。

把它想象成一个掉进你代码里的毛毛虫。两个方括号把毛毛虫关住不让它乱跑,方便你确认哪边是头哪边是尾。逗号是毛毛虫的脚,在身体的各个部分摇动着。

一旦有只毛毛虫拥有逗号的脚,从文学上来说它必须每一步都停顿一会儿。其它毛毛对这种庄严的风度十分崇拜。而我们的毛毛虫慈善家从不会把新鲜的树叶给那些可怜虫。

是的,数组是一些事物的集合,同时也把它们按一定顺序排列。

哈希

哈希是一个由大括号围着的字典。字典把单词和解释对应起来。Ruby通过用等号和大于号组合成的箭头来表明对应。

例如 {‘a’ => ‘aardvark’, ‘b’ => ‘badger’}

这次大括号成了一本书的封面和封底,看它们多像一本中间有褶皱的书。它们代表打开和关上我们的字典。

逗号代表翻开下一页。每一页中的单词后面跟着箭头指向定义。

{ 'name' => 'Peter', 'profession' => 'lion tamer', 'great love' => 'flannel' }

我没有举字典的例子是因为哈希中可以存放更多的内容。比如Peter。哈希像字典一样可以简单地查到信息。

正则表达式

正则表达式是一套以正斜杠包围的字符。

例如 /ruby/, /[0-9]+/ and /^\d{3}-\d{3}-\d{4}/。

正则表达式被用于在一段话中搜索单词或型式。两边的正斜杠是指针。

想像你拿着两个指针,中间是一个单词的格式。你在一本书中寻找着符合格式的单词,当找到时,指针就开始闪烁。你把正则表达式订在书上,一旁是闪闪发光的符合条件的单词。

噢,在你把指针刺进书里的时候,纸张打了个喷嚏。

Ruby用正则表达式查找数值,要比你把手指按在纸张上查找快多了。

运算符

你会用它们来在Ruby中运算和比较。浏览下表,认出一些。比如,加号减号等等。

** !  ~  *  /  %  +  -  &
<< >> |  ^  >  >= <  <= <=>
|| != =~ !~ && += -= == ===
.. ... not and or

关键字

Ruby中有一些保留在安全房间里的关键字,你不可以用它们作变量,或是按你的意愿重新定义功能。如果你那么做了,会收到一次官方的格式错误。

alias   and     BEGIN   begin   break   case    class   def     defined
do      else    elsif   END     end     ensure  false   for     if
in      module  next    nil     not     or      redo    rescue  retry
return  self    super   then    true    undef   unless  until   when
while   yield

这些是Ruby语言中最显赫的成员。我们将在下面三个章节欣赏它们组成的精巧的(碉堡了的)代码。

我再次建议你除去偏见,给自己一给宽广的视野。我会在下一部分测试你的精神。

3.如果我没有先把你当成一个小孩

我为你感到骄傲。每个人都会告诉你我是如何向他们吹嘘你的。你不停地阅读,往下翻,再阅读,再往下翻……“那些孩子……”我对别人说。“天哪,他们真的用心。我从没……”然后我因为太感动以至于痛哭。

接着我的心开始发出红光,穿透了我薄薄的,半透明的皮肤。他们只好给我输了10cc的javascript好让我恢复过来。(我对血液中毒素的抵抗力良好。)哥们儿,那些东西会让你把嘴里的桃子吐出来!

目前你的表现良好。但是我将化身严厉的教师。我需要看到你优秀的分数。直到现在,你除了大声说了几句话之外什么也没做。现在,我们需要一些理解力。

大声读出下面每个部分所用到的语句

5.times { print "Odelay!" }

我知道你想直接看答案了。这里有一个数字5,之后是一个方法.times,第一个螃蟹爪子开启了一个块。核心方法print不需要句号,后面是字符串”Odelay!”。最后一个爪子关闭了块。

大声读出下面每个部分所用到的语句

exit unless "restaurant".include? "aura"

和print方法一样,exit也是一个核心方法。如果你有注意看过关键字列表,你会知道unless也是一个关键字。字符串”restaurant”之后紧接着方法.include?,最后是字符串“aura”。

大声读出下面每个部分所用到的语句

 ['toast', 'cheese', 'wine'].each { |food| print( food.capitalize ) }

这只毛毛虫带来了一些美食。开头是一个数组。在数组中有三个字符串。整个数组被一个方法each尾随着。

在一个块中,块参数food顺着小小的管道滑进块里。首字母大写方法将变成了变量food的块参数进行了处理。处理过的数组被送往核心方法print。

再看一次例子,确认你能辨认出每个用到的语句。他们都有独特的外表,不是吗?深呼吸,平复一下情绪。现在,让我们解剖一段价值一只奶牛眼睛的代码。

4,一个帮助你成长的例子

大声读出下面每个部分所用到的语句

require 'net/http'
Net::HTTP.start( 'www.ruby-lang.org', 80 ) do |http|
  print( http.get( '/en/about/license.txt' ).body )
end

第一行是一个引入方法require。一个字符串’net/http’跟在方法后面。把第一行的代码当作是一个句子。我们正在让Ruby载入一些有帮助的代码, Net::HTTP库。

下面三行的是合在一起的。常量Net::HTTP 来自于我们刚才载入的库。我们正在使用库里的方法start。我们正在向这个方法里发送字符’www.ruby-lang.org’和数字80.

单词do开启了一个块。这个块中有一个块变量http。在块里,方法print被调用了。有什么被print了?

来自变量http的方法get被调用了。我们将带有地址的字符串’/en/about/license.txt’发给get。接着,另一个方法body连接在get之后。然后,块关闭了。

一切正常?出于好奇,让我们来猜猜这段代码会做什么?你充满希望地望着Ruby。如果什么也没有发生,请用力摇头将脑袋里的代码打碎成可以理解的小块。

比如,这种格式已经用过了很多次:

_variable_ . _method_ ( _method arguments_ )

你在块里见过它

http.get( '/en/about/license.txt' )

我们正使用Ruby获取一个网页。你可能在你的网页浏览器中使用过HTTP。HTTP是超文本传送协议。用于在网络中传送网页。就像一辆在网络中运送网页的公交车。在司机的帽子上绣着字母HTTP。

变量http是公交车的司机。方法是传送给司机的信息。去接一个叫做en/about/license.txt的网页。

接下来是后面连着的方法:

http.get( '/en/about/license.txt' ).body

在我们从司机那里带回了一个网页后,你可以这样读之前的代码:

_web page_ .body

还有这部分代码:

print( http.get( '/en/about/license.txt' ).body )

这些代码收到了网页。我们把一个body信息传送给网页,之后我们得到了存在一个字符串里的整个HTML。接着打印除了那个字符串。下一章里我们会探索所有这种的带句号的基础方法。那会很有趣。

所以,这段代码做了什么?它通过一个网络公交司机在屏幕上打印出了Ruby证书。

5.接下来,这次快速的旅行要做一个轻松的停留。


Refference: