25 Ruby Code Factoids
1. phương thức ‘methods’ Trong Ruby một đối tượng Object có thể nhập .methods để xem tất cả các phương thức có thể của đối tượng đó. 2.3 .0 : 001 > 4. methods - Object . methods = > [ : %, :&, : * , : * * , : + , : + @ , : - , : ...
1. phương thức ‘methods’
Trong Ruby một đối tượng Object có thể nhập .methods để xem tất cả các phương thức có thể của đối tượng đó.
2.3.0 :001 > 4.methods - Object.methods => [:%, :&, :*, :**, :+, :+@, :-, :-@, :/, :<<, :>>, :[], :^, :abs, :abs2, :angle, :arg, :between?, :bit_length, :byte, :bytes, :ceil, :chr, :coerce, :conj, :conjugate, :day, :days, :denominator, :div, :divmod, :downto, :even?, :exabyte, :exabytes, :fdiv, :floor, :fortnight, :fortnights, :gcd, :gcdlcm, :gigabyte, :gigabytes, :hour, :hours, :i, :imag, :imaginary, :in_milliseconds, :integer?, :kilobyte, :kilobytes, :lcm, :magnitude, :megabyte, :megabytes, :minute, :minutes, :modulo, :month, :months, :multiple_of?, :negative?, :next, :nonzero?, :numerator, :odd?, :ord, :ordinal, :ordinalize, :petabyte, :petabytes, :phase, :polar, :positive?, :pred, :quo, :rationalize, :real, :real?, :rect, :rectangular, :remainder, :round, :rszf, :second, :seconds, :singleton_method_added, :size, :step, :succ, :terabyte, :terabytes, :times, :to_bn, :to_c, :to_d, :to_default_s, :to_f, :to_formatted_s, :to_i, :to_int, :to_r, :truncate, :upto, :week, :weeks, :year, :years, :zero?, :|, :~]
2. biến _
Trong IRB sử dụng biến gạch dưới _ sẽ tổ chức đánh gia dòng cuối cùng của mã thực thi.
Khi biến được sử dụng trong code nó là một chỉ số từ các developer rằng tham số này sẽ không được sử dụng. Ví dụ: "Được chia thành các cột 4"
2.3.0 :002 > [0,1,2,3,4,5,6,7,9].group_by.with_index {|_,index| index % 4 }.values => [[0, 4, 9], [1, 5], [2, 6], [3, 7]]
Trong khuôn khổ Minitest, bắt đầu từ phiên bản 5.6.0, việc sử dụng gạch dưới là một alias cho các thử nghiệm kiểu này.
spec(4).must_be :even? _(4).wont_be :odd?
3. phương thức instance_exec
Phương thức instance_exec có sẵn cho tất cả các Object, và mọi thứ tron Ruby đều là một đối tượng, và khi bạn sử dụng nó bạn mở singleton_class của đối tượng để làm việc. Mọi thứ bạn có thể làm trong một Class bạn cũng có thể làm trong một instance_exec
num = Object.new num.instance_exec { def == other other == 3 end } num == 4 # => false num == 3 # => true
Bạn còn có thể sử dụng nó trong một Proc nó có thể khiến mọi người điên lên nếu bạn làm. Nhưng đây chỉ để bạn biết rằng có thể làm nó:
prc = proc {|num| num == 4} prc.instance_exec { def == other; other == 3 end } prc.call(4) # => true prc.call(3) # => false prc == 4 # => false prc == 3 # => true
4. Đối tượng Enumerator::Lazy
Một đối tượng Enumerator::Lazy sẽ cho bạn trở lại một đối tượng cùng một lúc từ bộ sưu tập của bạn với việc truy cập tùy chọn trên mỗi mục.
def do_the_lazy(array_input) Enumerator::Lazy.new(array_input) do |yielder, value| yielder << value end end x = do_the_lazy([1,2,3,4,5,6]) # => #<Enumerator::Lazy: [1, 2, 3, 4, 5, 6]:each> x.next # => 1 x.next # => 2 x.next # => 3 x.force # => [1, 2, 3, 4, 5, 6]
5. Struct has Enumerable as its ancestor
Bạn có thể sử dụng bất kỳ phương thức từ nó và viết một số phương thức nhỏ trên Struct mình.
class Pair < Struct.new(:first, :second) def same? inject(:==) end def add reduce(:+) end end a = Pair.new(4,4) # => #<struct Pair first=4, second=4> a.same? # => true a.add # => 8 b = Pair.new(5,6) # => #<struct Pair first=5, second=6> b.same? # => false b.add # => 11
6. $$
biến $: là biến load đường dẫn cho các gem Ruby. Cũng có thể thông qua $LOAD_PATH. Bạn có thể thêm các thư mục hiện tại đến đường dẫn tải của bạn với:
$: << '.'
7. inspect
Phươngthức inspect biểu diễn mặc định của một đối tượng Object khi bạn gọi Class#new và nó hiển thị nó trên dòng tiếp theo
class Human < Struct.new(:name, :age) def inspect "#{name} is a human of age #{age}" end end joe = Human.new("Joe", 43) # => Joe is a human of age 43
8. Hash#invert
Phương thức invert cho phép bạn đảo ngược Hash cặp khóa - giá trị của bạn.
{a: 1, b: 2}.invert # => {1=>:a, 2=>:b}
9. Method#to_proc
Bạn có thể chuyển các phương thức tớ proc nhờ to_proc. Lưu ý Chúng chỉ thực hiện khi cùng một loại đối tượng mà chúng đc định nghĩa.
def plus_one(x) x + 1 end proc_increment = method(:plus_one).to_proc proc_increment.call(4) # => 5 [1,3,5,9].map(&proc_increment) # => [2, 4, 6, 10]
10. require_relative
require_relative là một cách thuận tiện để tải tập tin ruby khác liên quan đến các tập tin vị trí hiện tại của bạn.
11. instance_methods
Trên bất kỳ class nào bạn có thể gọi phương thức instance_methods để tìm ra những trường hợ riêng của lớp sẽ được định nghĩa trên chúng.
12. Enumerable
Enumerable là một module mà bao gồm các kiểu siêu tập cơ bản như Array, Hash, hay Struct. Vì vậy, tất cả các loại đối tượng sẽ bao gồm các phương thức từ Enumerable.
class Conversation < ActiveRecord::Base enum status: [ :active, :archived ] end # conversation.update! status: 0 conversation.active! conversation.active? # => true conversation.status # => "active" # conversation.update! status: 1 conversation.archived! conversation.archived? # => true conversation.status # => "archived" # conversation.status = 1 conversation.status = "archived" conversation.status = nil conversation.status.nil? # => true conversation.status # => nil
13. defined?
từ khoá phương thức defined?hữu ích cho việc kiểm tra bất kì module, class, method được định nghĩa công khai. Trên các class trên các module bạn có có thể gọi các phương thức method_defined?, public_method_defined?, private_method_defined?, và protected_method_defined?
defined? Person # => nil class Person end # => nil defined? Person # => "constant"
14. string % value(s)
Bạn có thể chèn với loại chuyển đổi thành chuỗi bằng cách sử dụng phương thức phần trăm % như sau:
"Number: %f %f" % [1,2] # => Number: 1.000000 2.000000 "Number: %e" % "6" # => "Number: 6.000000e+00"
15. ternary operator _ ? _ : _
Nó là một cách viết tắt thay câu lệnh if else. nếu giá trị trước dấu chấm hỏi là đúng thì trả lại hàng đầu tiên sau dấu chấm hỏi. Nếu sai thì di chuyển qua các dấu chấm. Nó được khuyến khích sử dụng nếu biểu thức chỉ trên 1 dòng, có thể sử dụng thêm các dấu ngoặc cho dễ hiểu
true ? 10 : 20 # => 10 false ? 10 : 20 # => 20 false ? 10 : 20 ? 30 : 40 # => 30 false ? 10 : !20 ? 30 : 40 # => 40 false ? 10 : 20 ? 30 ? 50 : 60 : 40 # => 50 false ? 10 : 20 ? !30 ? 50 : 60 : 40 # => 60 false ? 10 : !20 ? 30 ? 50 : 60 : 40 # => 40
16. ruby -e “#code”
Chạy đoạn mã ruby từ dòng lệnh
ruby -e "puts 1 + 1" # => 2
17. %[]
%[Hello #{ "World!" } "Quoted" and 'quoted!'] # => "Hello World! "Quoted" and 'quoted!'"
18. erb
ERB là một thư viện của Ruby và bạn có thể sử dụng nó để thêm code Ruby với documents/strings khác.
require "erb" ERB.new(%[<html><body>Hello <%= "Wor" + "ld!" %></body></html>]).result # => "<html><body>Hello World!</body></html>"
19. ‘self’ có thể thay thê bằng tên Object
module Apple def Apple.chew "munch munch" end end Apple.chew # => "munch munch" def Apple.cut "chop chop" end Apple.cut # => "chop chop" class A def A.foo "bar" end end A.foo # => "bar"
20. Đối tượng có phạm vi cao hơn có thể được truy cập với ::
module A def self.test "FOO" end end module Thing module A def self.test "BAR" end end def Thing.inner A.test end def Thing.outer ::A.test end end Thing.outer # => "FOO" Thing.inner # => "BAR"
21. prepend
prepend thêm một module vào chuỗi gần đây nhât của lớp tổ tiên. Phương thức sẽ được gọi đầu tiên.
module A def split self.upcase end end String.prepend A String.ancestors # => [A, String, Comparable, Object, Kernel, BasicObject] "asdf".split # => "ASDF"
22. super
super gọi tên phương thức hiện thời của lớp tổ tiên và tiếp tục cho đến khi tìm được định nghĩa.
module A def split(*_) super("a") end end class B < String def split super("b") end end b = B.new("123abc") # => "123abc" b.split # => ["123a", "c"] B.ancestors # => [B, String, Comparable, Object, Kernel, BasicObject] String.prepend A b.split # => ["123", "bc"] B.ancestors # => [B, A, String, Comparable, Object, Kernel, BasicObject]
23. arity
arity cho bạn biết có bao nhiêu tham số mộột Proc hay phương thức sẽ lấy.
->{}.arity # => 0 ->_{}.arity # => 1 ->_,_{}.arity # => 2 ->*_{}.arity # => -1 "".method(:upcase).arity # => 0 String.instance_method(:upcase).arity # => 0
23. class_eval with included
Sử dụng class_eval khi bạn đang viết các phương thức được đưa vào là cách tự nhiên hơn của việc update các class. Bạn sẽ viết định nghĩa của bạn cũng giống như khi bạn đang ở trong class.
class A end module Example def self.included(base) base.class_eval do def example "instance method" end def self.example "class method" end end end end A.include Example A.example "class method" A.new.example "instance method"
24. inherited
Khi bạn đang có một lớp kế thừa từ các lớp khác như là một "mixin" bạn có thể viết.
class Foo def self.inherited(base) base.class_eval do def bar "Drinking at the bar!" end end end def foo "bar" end end class A < Foo end A.new.foo # => "bar" A.new.bar # => "Drinking at the bar!" Foo.new.foo # => "bar" Foo.new.bar #NoMethodError: undefined method `bar' for #<Foo:0x00000001916378>
25. Infinity
Bạn có thể sử dụng phương thức detect để trả lại phần tư đầu tiên đánh giá là đúng
[1,5,9,11,13,15,18,21,24,26,28].detect(&:even?) # => 18 [1,5,9,11,13,15,18,21,24,26,28].detect {|number| number.even? } # => 18
Tham Khảo http://6ftdan.com/allyourdev/2016/01/13/101-ruby-code-factoids/