Day3 要来介绍Ruby
字串、数字,还有Ruby
的 ===
数字比起其他类别,还要来的单纯。不过身为Rails的工程师,必须知道Ruby
提供的语法
num = 10
num.even? # 是否为偶数
num.odd? # 是否为奇数
num.positive? # 是否为正数
num.negative? # 是否为负数
num.zero? # 是否为零
num.integer? # 是否为正数
⭐️ Ruby的目的为写得出让人愉悦的语法,所以除了上述的口语化语法以外,数字本身也有小巧思。
1000 #=> 1000
1_000 #=> 1000
10_00 #=> 1000
在Ruby
语言中,我们可以把_
当成是逗点, 若数字的位数太多,则可以加注底下下去。不过Ruby
底线的位置不会限制,因此写在哪里都可以。
⭐️ Ruby
使用随机数字的语法为rand
,而我们也可以透过+/-某个数字来做平移的效果。
rand(10) #=> 数字1-10
rand(10) + 10 #=> 数字10-20
⭐️ 处理除法方面,Ruby
必须小心整数相除的状况。在Ruby
程序语言中,所有皆为物件,而Integer
, Float
为不同物件,表现的行为也会不一样要注意。
1/2 #=> 0
1.0/2.0 #=> 0.5
1.to_f/2.to_f #=> 0.5
1.class #=> Integer
1.0.class #=> Float
⭐️ 如果想要了解线性代数,或者公职/研究所有用到线性代数的话,也可以使用下列的matrix
玩玩看。
require 'matrix'
⭐️ 如果要取概数,可以使用round
2.3465.round(2) #=> 2.35
⭐️ 可以使用format
,但型别就为字串。小心不要用字串来做数字的运算
format("%.2f", 2.3465) #=> "2.35"
format("%.2f", 2.3465).class #=> String
⭐️ 和Rails
数字有关的 helper
也有一些值得介绍的,像是如果要显示金额的话,可以使用(可参考这篇):
helper.number_to_currency(42.50) #=> "NT$42.50"
helper.number_to_currency(nil) #=> nil
helper.number_to_currency(42.50, unit: "Richard$") #=> "Richard$42.50"
Ruby
的字串有很多实用的写法,以下跟大家介绍一些目前自己常用的!
"admin/sub_order".camelize #=> "Admin::SubOrder"
"Admin::SubOrder".underscore #=> "admin/sub_order"
"admin/sub_order".dasherize #=> "admin/sub-order"
"book".pluralize #=> "books"
"person".pluralize #=> "people"
"fish".pluralize #=> "fish"
"books".singularize #=> "book"
"people".singularize #=> "person"
"book_and_person".pluralize #=> "book_and_people"
"book and person".pluralize #=> "book and people"
"BookAndPerson".pluralize #=> "BookAndPeople"
"books_and_people".singularize #=> "books_and_person"
"books and people".singularize #=> "books and person"
"BooksAndPeople".singularize #=> "BooksAndPerson"
"admin/sub_orders".humanize #=> "Admin/sub orders"
"admin/sub_orders".titleize #=> "Admin/Sub Orders"
"admin/sub_order".classify #=> "Admin::SubOrder"
"admin/sub_orders".classify #=> "Admin::SubOrder"
"admin/sub_order".tableize #=> "admin/sub_orders"
"Admin::SubOrder".tableize #=> "admin/sub_orders"
"Module".constantize #=> Module
"A::b::C".deconstantize #=> "A::b"
"A::b::C".demodulize #=> "C"
上述的这些用法如果搭配Ruby on Rails
的惯例,可以写出非常漂亮的语法。我们在对controllers
, models
命名的时候基本上都会按惯例,而只要命名符合规则,就可以用动态的方式写。以下是自己专案中的程序片段,依照惯例後就可以使用动态写法,因此可以精简化程序码。
下列为自己写过的某一支读取controller
的程序码。我们可以看到,以下使用了camelize
, singularize
, constantize
, classify
来对被included
的controller
做操作,达到程序码精简化的效果。
# controller.camelize.singularize.constantize
define_method("pre_query_#{controller}") do
# descent_exposure
return send(controller_name.to_sym) if respond_to?(controller_name.to_sym)
# instance_variable
instance_variable_set("@#{controller}", controller.camelize.singularize.constantize)
end
# Admin::#{controller.classify}Serializer
define_method(:default_viewable_lists) do |filtered_sub_orders, keys|
data_lists(viewable(filtered_sub_orders), "Admin::#{controller.classify}Serializer".constantize, keys)
end
我们不用懂上面的程序码在做什麽,我们把焦点放在两处:
controller.camelize.singularize.constantize
"Admin::#{controller.classify}Serializer".constantize
这里使用动态的写法,让被included
的档案都可以被读取到。至於#included
的话,我们会在Day14讲到
in?
与 include?
的用法差别在以下的例子!两者用法的差别就是倒过来放而已。
'a'.in?(['Cat', 'Dog', 'Bird']) # => false
['Cat', 'Dog', 'Bird'].include?('a') # => false
include?
为阵列的方法,照理说应该要放在Day4,但由於放在这里刚刚好,提前先提到。
有了start_with?
, end_with?
,可以少写很多正则表达式!
"popping_hoan".start_with? "popping" #=> true
"jquery".end_with? "query" #=> true
strip
为去除头尾的扣白,可以应用在填写表单。当使用者前後不小心加了空白,我们就可以使用strip
" I have leading and trailing white space ".strip
#=> "I have leading and trailing white space"
正规表达式是大部分的工程师,只要每用一次就要查一次的头痛地雷,正因为这样,对於一些常用的正则,我们可以把它放在心上。Ruby
, Rails
对一些常用的正则已经囊括进来,像是email
的验证便不用从头写过,ruby
的函式库也有很多正则表达的替代写法,例如上面提到的start_with?
, end_with?
。
我们来讲一下一些关於字串的用法
⭐️ 在字串中判断数字
def number?(obj)
obj = obj.to_s unless obj.is_a? String
/\A[+-]?\d+(\.[\d]+)?\z/.match(obj)
end
# / start of the regex
# \A start of the string to be matched
# [+-]? zero or one of '+' or'-'
# \d+ one or more of digit
# (\.\d+)? zero or one of 'one dot and 'one or more of digit''
# \z end of the string to be matched
# / end of the regex
⭐️ 字串判断A-Z(不是疫苗,是A到Z)
/\A[A-Z]+?\z/.match("ABC") # => #<MatchData "AZ">/\A[A-Z]+?\z/.match("A123") # => nil
⭐️ 字串判断A-Z和.-+
/\A[A-Z+-\.]+?\z/.match("AZZR.-+")
⭐️ 字串判断手机载具:第一个字元/
,後7个字元包含 A-Z
, .-+
/\A[\/][A-Z+-\.]{7}\z/.match("/AAA++++")
⭐️ 字串判断自然人凭证:2位大写+14位数字
/\A[A-Z]{2}[0-9]{14}\z/.match("AA22222222222222")
/\A[A-Z]{2}[0-9]{14}\z/ =~ ("AA22222222222222")
⭐️ 字串的取代也是很重要的语法,在Ruby
我们可以使用gsub
来取代字串,下列为一些取代的例子。
"chenhanting".gsub(/[aeiou]/, '*') #=> "ch*nh*nt*ng"
"chenhanting".gsub(/([aeiou])/, '<\1>') #=> "ch<e>nh<a>nt<i>ng"
"chenhanting".gsub(/./) {|s| s.ord.to_s + ' '} #=> "99 104 101 110 104 97 110 116 105 110 103 "
"chenhanting".gsub(/(?<foo>[aeiou])/, '{\k<foo>}') #=> "ch{e}nh{a}nt{i}ng"
'chenhanting'.gsub(/[eo]/, 'e' => 3, 'o' => '*') #=> "ch3nhanting"
"Me & You".gsub(/[&]/, 'and') #=> "Me and You"
ActiveSupport
是Rails
的宝库,很多东西都可以在 ActiveSupport
找,ActiveSupport
在rails
的地位就相当於 Javascript
的 lodash
,只不过不一样的地方是 lodash
为外部库、ActiveSupport
则为Rails
的内建库。
vehicle = ActiveSupport::StringInquirer.new('car')
vehicle.car? # => true
vehicle.bike? # => false
variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
variants.phone? # => true
variants.tablet? # => true
variants.desktop? # => false
variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
variants.any? # => true
variants.any?(:phone, :tablet) # => true
variants.any?('phone', 'desktop') # => true
variants.any?(:desktop, :watch) # => false
Ruby的等於一共有这几种:equal?
, ==
, eql?
。等於的方法,常用的为後面两种,eql?
较==
还严格,不过基本上没太多严格定义,两者可以混用。
5 == 5.0 # true
5.eql? 5.0 # false
但跟===
的概念完全不一样,===
在Ruby
的概念为case when
,跟等於一点关系都没有。我们实际举一些范例,跟附上说明:
# 1 是不是符合在1到10里面
(1..10) === 1
# 'abcdef'字串是不是符合 /abc/ 的正则表达
/abc/ === 'abcdef'
# 'abcdef' 是不是 string
String === 'abcdef'
然而===
的写法实在不好看懂,Ruby
有很多写法可以语法糖可以替代 ===
,以下是推荐的好写法
# Bad
(1..10) === 1
/abc/ === 'abcdef'
String === 'abcdef'
# Good, uses synonym method
(1..10).include?(1)
/abc/ =~ 'abcdef'
'abcdef'.is_a?(String)
接着,我们来比较case when
vs ===
。以下为使用case when
,与使用===
的比对
def display_installment(v)
case v
when 0 then '一次付清'
when 3 then '3期'
when 6 then '6期'
end
end
# 被比较的放在右侧
def display_installment(v)
if 0 === v
'一次付清'
elsif 3 === v
'3期'
elsif 6 === v
'6期'
end
end
display_installment(6)
会拿case when
与 ===
当例子,是因为case when
使用 ===
实作
%q
, %Q
都可以包字串,但 %Q
代表双引号,%q
代表单引号。双引号的字串里面可以放变数、放特殊字元。因此若要使用,就使用%Q
,而不要使用%q
。
%Q(han react
ruby
vue it2021)
#=> "han react\nruby\nvue it2021"
str = 'apple'
%Q[#{str} is "DELICIOUS"]
#=> "apple is \"DELICIOUS\"
实际上,我们可以在helper
里面,可以使用%Q
回传html
。
def get_form(action, options = {})
# ......
%Q(
<form name='xxxx' method='post' action='#{url}'>
#{params.map do |k,v|
"<input name='#{k}' type='hidden' value='#{v}'/>"
end.join("")
}
<input type='submit'/>
</form>
)
end
我们在helper
使用%Q
,来引入 recaptcha
的样式。
module ApplicationHelper
RECAPTCHA_SCORE_SITE_KEY = ENV['RECAPTCHA_SCORE_SITE_KEY']
RECAPTCHA_CHECKBOX_SITE_KEY = ENV['RECAPTCHA_CHECKBOX_SITE_KEY']
def include_recaptcha_js
raw %Q{<script src="https://www.google.com/recaptcha/enterprise.js?render=#{RECAPTCHA_SCORE_SITE_KEY}"></script>}
end
def recaptcha_execute(action)
raw %Q{
<input name="recaptcha_token" type="hidden" id="__recaptcha_token__"/>
<script>
grecaptcha.enterprise.ready(function() {
grecaptcha.enterprise.execute('#{RECAPTCHA_SCORE_SITE_KEY}', {action: '#{action}'})
.then((token) => {
console.log('reCAPTCHA score action', '#{action}');
console.log('reCAPTCHA score token:', token);
document.getElementById("__recaptcha_token__").value = token;
})
.catch((error) => {
console.log(`The unknown error has occurred: ${error}`);
});
});
</script>
}
end
end
chomp
:移除结尾字元chop
concat
range
'kitty'[1..2] #=>it
ljust
reverse
⭐️ 显示子订单的出货来源
# 有厂牌 & 店柜资讯: iphone-新庄店
# 只有厂牌资讯: iphone
#
[sub_order.brand.title, sub_order.store.title_zh].compact.join('-')
⭐️ 将We have lunch at 12 o'clock
句子的英文字转成数字,其余特殊符号如空白、引号剔除,并用底线连接。以下为对应表跟实际内容!
A => 1
B => 2
C => 3
...
Z => 26
str = "We have lunch at 12 o'clock"
str.downcase.chars.select { |s| /\A[A-Z|a-z]+?\z/.match(s) }.map{|n| n.ord - 'a'.ord}.join('_')
#=> "22_4_7_0_21_4_11_20_13_2_7_0_19_14_2_11_14_2_10"
<<: GitHub 基本功能介绍 - 开始建立第一个储存库
>>: Day 3. Hashicorp Nomad: Server configuration for production
Odoo选单选择 [设定] -> 画面右下角有个 [启用开发者模式], 选下去! 这就完成啦!...
今天开始到结束,要进入到实际 Dapp 的应用了,但在应用之前要先会安装 metamask。 因为要...
您准备好了解 Microsoft 安全合规性和身份基础知识了吗? 由於 IT 行业处於永无止境的进步...
使用大括号与驼峰式命名来处理 DOM 是它与原生 jS 的差别。 //jS 写法 <butto...
前一篇介绍了如何运用 Laravel 框架设计模式规划大型专案,当中有提到Model,今天就来介绍这...