Rubyセルフテストシリーズ

7296 ワード

本文はruby-triviaとruby-styleに基づいて完成して、部分の問題を節選して、そして更に原理を探究して、自身のruby基礎に対する理解と応用を強化します.
Language Characteristics and Core Objects
Q: Is Ruby a statically typed or a dynamically typed language? A: Dynamically typed since type checking is done at runtime.
Q: Is Ruby a strongly typed or a weakly typed language? A: Strongly typed since an object's type is checked before an operation is performed on it.
Q: What is the difference between a statement and an expression in Ruby? A: All statements are expressions in Ruby since all statements return a value. (expressions > statements)
Data Types
Q: Does String include the Enumerable module? A: No.
Q: What method might you use to enumerate over a string? A: String#each_char
Hash
Q: How might you specify a default value for a hash? A: Pass the default values as arguments to::new on initialization or change the default directly with the method Hash#default. You may also provide a default at the time of query with Hash#fetch. C:場合によってはHash#fetchを使用するのが適切です.
  • 存在すべきハッシュキーを処理する際には、Hash#fetch
  • を用いる.
    heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
    
    #   -           ,         
    heroes[:batman] # => 'Bruce Wayne'
    heroes[:supermann] # => nil
    
    #   - fetch     KeyError          
    heroes.fetch(:supermann)
    
  • ハッシュキーの値にデフォルト値を指定する場合、カスタムロジックではなくHash#fetchを使用する傾向があります.
  • batman = { name: 'Bruce Wayne', is_evil: false }
    
    #   -        ||    ,       ,          
    batman[:is_evil] || true # => true
    
    #   - fetch               
    batman.fetch(:is_evil, true) # => false
    
  • デフォルト値を提供する評価コードが副作用またはオーバーヘッドが大きい場合、Hash#fetchのblock形式
  • を使用する傾向がある.
    batman = { name: 'Bruce Wayne' }
    
    #   -         ,      ,          
    batman.fetch(:powers, obtain_batman_powers) # obtain_batman_powers     
    
    #   -         ,     KeyError  ,      
    batman.fetch(:powers) { obtain_batman_powers }
    

    Q: Does Hash use #== or #eql? to compare hash keys? A: #eql? C: Why? What's the different between them? Hashは#eqlを使いますか?比較してみましょう.Numericは、eqlではなく#==で比較します.この場合、#eql?もっと厳しい比較ができます.Objectのオブジェクトについて、#eql?#==と同じです.このことから,Numericは例外であることが分かる.equal?は、両者が同じオブジェクト(同じ値、同じtype)であるかどうかをチェックします.
    #   Numeric
    x = 1
    puts x.object_id  # => 3
    
    y = 1
    puts y.object_id  # => 3
    
    z = 1.0
    puts z.object_id  # => -36028797018963966
    
    x == y  # true     object
    x.eql? y  # true    object
    
    x == z   #true   object,  content  
    x.eql? z  #false   object,      type,x Fixnum,y Float
    
    #   Array object
    x = [1, 2, 3]
    y = [3, 2, 1]
    z = [1, 2, 3]
    
    x.object_id  # => 70244601475800
    y.object_id  # => 70244601492000
    x.eql?(y) #=> false
    
    x.object_id  # => 70244601475800
    z.object_id  # => 70244601475800
    x.eql?(z) #=> true
    
    x.object_id  # => 70244601475800
    s = y.sort  # => [1, 2, 3]
    s.object_id  # => 70244618664060
    x.class # => Array
    y.class # => Array
    x == s #=> true    value
    x.eql?(s) #=> true    value type
    x.equal?s  #=> false   value type,         
    

    Q: What's is the precedence of &&, and, or, =, ||? A: && > || > = > (and, or)
    Q:. vs :: A:クラスメソッドを呼び出す場合、彼らには違いはありません.ただし、::を使用してconstantとnamespaceにアクセスできます.
    Q:!= vs <=>(spaceship)A:!=は等しくない.<=>、左が右より大きいと1を返し、0を返し、-1を返します.
    Q: What's true and false in ruby? A: Everything in Ruby is true except false and nil . TrueClass , FalseClass , but can't create a new instance for them. true and false are the only things we can get. We can recognize them by either using nil? or false on == left-hand.
    Q: What is duck type? A: Walk like a duck, yip like a duck, it's a duck. In an other word, interface over type.
    Q:
    h = Hash.new
    h[:s] = 'ok'
    

    Can you retrive 'ok' by h['s'] ? A: You cannot. Since the Hash class in Ruby’s core library retrieves values by doing a standard == comparison on the keys. This means that a value stored for a Symbol key (e.g. :my_value) cannot be retrieved using the equivalent String (e.g. ‘my_value’). On the other hand, HashWithIndifferentAccess treats Symbol keys and String keys as equivalent so that the following would work:
    Q: #joins vs #includes in Rails ActiveRecord A: #joins performs an inner join between two tables.
    orders = Order.joins(:listing)
    => SELECT "orders".* FROM "orders" INNER JOIN "listings" ON "listings"."id" = "orders"."listing_id"
    

    内部接続T 1の各行R 1について、T 2において接続条件を満たす1つまたは複数の行を見つけることができれば、これらの条件を満たす各行は、接続テーブルにおいて1行を生成する.In another word, It will retrieve all records where listing_id (of orders table) is equal to listing.id (listings table)
    このときlistingのデータは取り出されませんでした.すべてのorderの関連関係listingのプロパティを取得する場合は、データベースを確認します.
    order_1 = orders.first
    //                ,      。
    => #
    
    order_1.listing.address
    //        order  listing        ,        。
    => SELECT  "listings".* FROM "listings" WHERE "listings"."id" = $1 LIMIT 1  [["id", 1]]
    
    #includes performs a left outer like join between the two tables.
    orders = Order.includes(:listing)
    => SELECT "orders".* FROM "orders"
    => SELECT "listings".* FROM "listings" WHERE "listings"."id" IN (1, 2, 3, 4)
    

    この場合、左外部接続と同様に実行されます.左外部ジョイン:最初に内部ジョインを1回実行します.次に、各T 1においてT 2に一致する行が見つからない行に対して、T 2に対応する列をNULLで補完する行を生成する.したがって、生成された接続テーブルには、T 1の各ローから少なくとも1つのコピーが常に含まれる.なぜ「左外接続に似ている」と言うのですか?通常の左外部接続は、次のように書かれています.
    SELECT "orders".* FROM "orders" LEFT JOIN "listings" ON "listings"."id" = "orders"."listing_id";
    

    しかしrailsでは見られませんでしたこれはrails 4では、LEFT OUTER JOINのsqlクエリ文を手動で書く必要があるからです.
    orders = Order.joins('LEFT OUTER JOIN "listings" ON "listings"."id" = "orders"."listing_id"')
    

    実はrailsが私たちに手伝ってくれたのは、まずすべてのorders表の記録を取り出すことです.次にlistingsテーブルからordersテーブルレコードと一致するレコードを取り出し、メモリに保存します.
    幸いなことにrails 5には、LEFT OUTER JOINSを実行するための新しい方法#letf_outer_joinsが追加された.
    次に、orderの関連関係listingsのプロパティをクエリーします.
    order_1 = orders.first
    //     
    => #
    
    order_1.listing.address
    //  listings                 ,              。
     => {"city"=>"Nantes (44000)", "street_number"=>"", "region"=>"Pays de la Loire", "street"=>""}
    

    再クエリ時にデータベースが読み込まれないことがわかります.