striuct 0.0.11.1 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.rdoc +128 -35
- data/Manifest.txt +21 -6
- data/README.ja.rdoc +142 -83
- data/README.rdoc +130 -73
- data/Rakefile +5 -3
- data/example/benchmarks.rb +56 -0
- data/{example.rb → example/example.rb} +81 -70
- data/example/see_trace.rb +28 -0
- data/lib/striuct/abstract.rb +74 -0
- data/lib/striuct/conditions.rb +228 -0
- data/lib/striuct/frame.rb +8 -0
- data/lib/striuct/subclassable/basic.rb +135 -0
- data/lib/striuct/{classutil.rb → subclassable/classutil.rb} +5 -5
- data/lib/striuct/subclassable/eigen/basic.rb +38 -0
- data/lib/striuct/subclassable/eigen/constructor.rb +58 -0
- data/lib/striuct/subclassable/eigen/frame.rb +39 -0
- data/lib/striuct/subclassable/eigen/handy.rb +92 -0
- data/lib/striuct/subclassable/eigen/inner.rb +224 -0
- data/lib/striuct/subclassable/eigen/macro.rb +108 -0
- data/lib/striuct/subclassable/eigen/safety.rb +56 -0
- data/lib/striuct/subclassable/frame.rb +33 -0
- data/lib/striuct/subclassable/handy.rb +57 -0
- data/lib/striuct/subclassable/hashlike.rb +133 -0
- data/lib/striuct/subclassable/inner.rb +108 -0
- data/lib/striuct/subclassable/safety.rb +72 -0
- data/lib/striuct/subclassable/yaml.rb +14 -0
- data/lib/striuct/version.rb +2 -2
- data/lib/striuct.rb +3 -2
- data/test/test_striuct.rb +649 -20
- metadata +55 -24
- data/lib/striuct/core.rb +0 -56
- data/lib/striuct/import.rb +0 -95
- data/lib/striuct/subclass.rb +0 -262
- data/lib/striuct/subclass_eigen.rb +0 -428
- data/test/test_helper_import.rb +0 -4
- data/test/test_striuct_import.rb +0 -42
    
        data/History.rdoc
    CHANGED
    
    | @@ -1,41 +1,134 @@ | |
| 1 | 
            +
            === 0.1.7 2012-1-26
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * add:
         | 
| 4 | 
            +
              * default with Proc
         | 
| 5 | 
            +
              * detail error message in Subclass.#[]=
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * fix
         | 
| 8 | 
            +
              * class duplicating
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            === 0.1.6 2012-1-25
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            * delete:
         | 
| 13 | 
            +
              * import.rb
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * modify:
         | 
| 16 | 
            +
              * Subclass.#define
         | 
| 17 | 
            +
              * naming risks (add bad name "_foo")
         | 
| 18 | 
            +
              * Conditions.#GENERICS (enum prior all? to each_value.all?)
         | 
| 19 | 
            +
              * timing of check default value
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            * add:
         | 
| 22 | 
            +
              * detail error message in Subclass.#define
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            * fix:
         | 
| 25 | 
            +
              * inherited behavior
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            === 0.1.5 2012-1-17
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            * add:
         | 
| 30 | 
            +
              * #lock, #lock?
         | 
| 31 | 
            +
              * some Specific Conditions
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            * note:
         | 
| 34 | 
            +
              multiple conditions for 'or', dupulicated for direct throw member macro
         | 
| 35 | 
            +
              please use .#OR method in this case
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            === 0.1.4 2012-1-16
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            * modify:
         | 
| 40 | 
            +
              * trace logs
         | 
| 41 | 
            +
              * naming risks(add bad name "to_foo")
         | 
| 42 | 
            +
              * Subclass#unassign
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            * add:
         | 
| 45 | 
            +
              * Specific Conditions
         | 
| 46 | 
            +
                (for Syntax Sugar of useful Functional Conditions)
         | 
| 47 | 
            +
              * Subclass.#each_index
         | 
| 48 | 
            +
              * Subclass.#valid?
         | 
| 49 | 
            +
              * Subclass#clear_at, reset_at
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            === 0.1.3 2012-1-10
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            * add:
         | 
| 54 | 
            +
              * Subclass.#alias_member
         | 
| 55 | 
            +
              * Subclass.#valid?
         | 
| 56 | 
            +
              * Subclass#valid?
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            === 0.1.2 2012-1-9
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            * modify:
         | 
| 61 | 
            +
              * Subclass.#hash
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            * add:
         | 
| 64 | 
            +
              * Subclass.#to_yaml
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            === 0.1.1 2011-12-26
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            * modify:
         | 
| 69 | 
            +
              * Subclass.#sufficient?
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            * add:
         | 
| 72 | 
            +
              * Subclass.#empty?
         | 
| 73 | 
            +
              * Subclass.#has_value? (value?)
         | 
| 74 | 
            +
              * Subclass.#flatten
         | 
| 75 | 
            +
              * Subclass.#select! (keep_if)
         | 
| 76 | 
            +
              * Subclass.#select
         | 
| 77 | 
            +
              * Subclass.#reject! (delete_if)
         | 
| 78 | 
            +
              * Subclass.#reject
         | 
| 79 | 
            +
              * Subclass.#assoc
         | 
| 80 | 
            +
              * Subclass.#rassoc
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            * fix
         | 
| 83 | 
            +
              * Subclass.#sufficient?
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            === 0.1.0 2011-12-25
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            * modify:
         | 
| 88 | 
            +
              * Subclass.#define
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            * add:
         | 
| 91 | 
            +
              * Subclass.#[] (alias load_pairs)
         | 
| 92 | 
            +
              * Subclass.#to_h
         | 
| 93 | 
            +
             | 
| 1 94 | 
             
            === 0.0.11 2011-12-23
         | 
| 2 95 |  | 
| 3 | 
            -
            * modify
         | 
| 4 | 
            -
              * Subclass | 
| 96 | 
            +
            * modify:
         | 
| 97 | 
            +
              * Subclass.#cname?
         | 
| 5 98 |  | 
| 6 99 | 
             
            * add:
         | 
| 7 100 | 
             
              * inference checker
         | 
| 8 101 |  | 
| 9 102 | 
             
            === 0.0.10 2011-12-23
         | 
| 10 103 |  | 
| 11 | 
            -
            * delete
         | 
| 12 | 
            -
              * Subclass | 
| 104 | 
            +
            * delete:
         | 
| 105 | 
            +
              * Subclass.#lock, Subclass.#unlock?
         | 
| 13 106 |  | 
| 14 | 
            -
            * modify
         | 
| 15 | 
            -
              * Subclass | 
| 107 | 
            +
            * modify:
         | 
| 108 | 
            +
              * Subclass.#freeze
         | 
| 16 109 | 
             
              * has_condition? -> has_conditions?
         | 
| 17 | 
            -
              * Subclass | 
| 110 | 
            +
              * Subclass.#lock, Subclass.#lock? -> .close, .closed?
         | 
| 18 111 |  | 
| 19 112 | 
             
            * add:
         | 
| 20 | 
            -
              * Subclass | 
| 21 | 
            -
              * Subclass | 
| 113 | 
            +
              * Subclass.#protect_level   # class macro
         | 
| 114 | 
            +
              * Subclass.#default?
         | 
| 22 115 |  | 
| 23 116 | 
             
            === 0.0.9 2011-12-21
         | 
| 24 117 |  | 
| 25 | 
            -
            * delete
         | 
| 118 | 
            +
            * delete:
         | 
| 26 119 | 
             
              * Striuct.load_pairs
         | 
| 27 | 
            -
              * Subclass | 
| 28 | 
            -
              * Subclass | 
| 29 | 
            -
              * Subclass | 
| 120 | 
            +
              * Subclass.#conditions
         | 
| 121 | 
            +
              * Subclass.#procedures
         | 
| 122 | 
            +
              * Subclass.#defaults
         | 
| 30 123 |  | 
| 31 124 | 
             
            * add:
         | 
| 32 125 | 
             
              * Striuct.define
         | 
| 33 | 
            -
              * Subclass | 
| 34 | 
            -
              * Subclass | 
| 126 | 
            +
              * Subclass.#lock
         | 
| 127 | 
            +
              * Subclass.#default_for
         | 
| 35 128 |  | 
| 36 129 | 
             
            * fix:
         | 
| 37 | 
            -
              * Subclass | 
| 38 | 
            -
              * Subclass | 
| 130 | 
            +
              * Subclass.#inspect
         | 
| 131 | 
            +
              * Subclass.#to_s
         | 
| 39 132 |  | 
| 40 133 | 
             
            * note:
         | 
| 41 134 | 
             
              * innner name changed "procedure" to "flavor"
         | 
| @@ -43,30 +136,30 @@ | |
| 43 136 | 
             
            === 0.0.8 2011-12-18
         | 
| 44 137 |  | 
| 45 138 | 
             
            * modify:
         | 
| 46 | 
            -
              * Subclass | 
| 47 | 
            -
              * Subclass | 
| 139 | 
            +
              * Subclass.#define
         | 
| 140 | 
            +
              * Subclass.#accept?
         | 
| 48 141 | 
             
              * functional checker's action:
         | 
| 49 142 | 
             
                Proc: context to instance
         | 
| 50 143 | 
             
                Method: === to call
         | 
| 51 144 |  | 
| 52 145 | 
             
            * add:
         | 
| 53 | 
            -
              * Subclass | 
| 146 | 
            +
              * Subclass.#default
         | 
| 54 147 |  | 
| 55 148 | 
             
            * fix:
         | 
| 56 | 
            -
              * Subclass | 
| 149 | 
            +
              * Subclass.#values_at
         | 
| 57 150 |  | 
| 58 151 | 
             
            === 0.0.7 2011-12-16
         | 
| 59 152 |  | 
| 60 153 | 
             
            * modify:
         | 
| 61 154 | 
             
              * called macro's block to procedure 
         | 
| 62 | 
            -
              * public to private Subclass | 
| 155 | 
            +
              * public to private Subclass.#unlock
         | 
| 63 156 |  | 
| 64 157 | 
             
            * add:
         | 
| 65 | 
            -
              * Subclass | 
| 66 | 
            -
              * Subclass | 
| 67 | 
            -
              * Subclass | 
| 68 | 
            -
              * Subclass | 
| 69 | 
            -
              * Subclass | 
| 158 | 
            +
              * Subclass.#define
         | 
| 159 | 
            +
              * Subclass.#accept?
         | 
| 160 | 
            +
              * Subclass.#restrict?
         | 
| 161 | 
            +
              * Subclass.#assign?
         | 
| 162 | 
            +
              * Subclass.#assign
         | 
| 70 163 |  | 
| 71 164 | 
             
            * fix:
         | 
| 72 165 | 
             
              * use clone method ( initialize_copy )
         | 
| @@ -77,13 +170,13 @@ | |
| 77 170 | 
             
              * error type in some methods
         | 
| 78 171 |  | 
| 79 172 | 
             
            * add:
         | 
| 80 | 
            -
              * Subclass | 
| 81 | 
            -
              * Subclass | 
| 82 | 
            -
              * Subclass | 
| 83 | 
            -
              * Subclass | 
| 84 | 
            -
              * Subclass | 
| 85 | 
            -
              * Subclass | 
| 86 | 
            -
              * Subclass | 
| 173 | 
            +
              * Subclass.#sufficent?
         | 
| 174 | 
            +
              * Subclass.#define
         | 
| 175 | 
            +
              * Subclass.#sufficent?
         | 
| 176 | 
            +
              * Subclass.#secure?
         | 
| 177 | 
            +
              * Subclass.#lock?
         | 
| 178 | 
            +
              * Subclass.#lock
         | 
| 179 | 
            +
              * Subclass.#unlock
         | 
| 87 180 |  | 
| 88 181 | 
             
            * fix:
         | 
| 89 182 | 
             
              * typo
         | 
| @@ -96,7 +189,7 @@ | |
| 96 189 |  | 
| 97 190 | 
             
            === 0.0.4 2011-12-13
         | 
| 98 191 |  | 
| 99 | 
            -
            * divide modules for  | 
| 192 | 
            +
            * divide modules for Subclass.#methods
         | 
| 100 193 | 
             
            * modify return values for void methods
         | 
| 101 194 |  | 
| 102 195 | 
             
            === 0.0.3 2011-12-12
         | 
    
        data/Manifest.txt
    CHANGED
    
    | @@ -3,13 +3,28 @@ Manifest.txt | |
| 3 3 | 
             
            README.rdoc
         | 
| 4 4 | 
             
            README.ja.rdoc
         | 
| 5 5 | 
             
            Rakefile
         | 
| 6 | 
            -
            example.rb
         | 
| 7 6 | 
             
            lib/striuct.rb
         | 
| 8 | 
            -
            lib/striuct/ | 
| 7 | 
            +
            lib/striuct/frame.rb
         | 
| 9 8 | 
             
            lib/striuct/version.rb
         | 
| 10 | 
            -
            lib/striuct/ | 
| 11 | 
            -
            lib/striuct/ | 
| 12 | 
            -
            lib/striuct/ | 
| 13 | 
            -
            lib/striuct/ | 
| 9 | 
            +
            lib/striuct/abstract.rb
         | 
| 10 | 
            +
            lib/striuct/conditions.rb
         | 
| 11 | 
            +
            lib/striuct/subclassable/frame.rb
         | 
| 12 | 
            +
            lib/striuct/subclassable/classutil.rb
         | 
| 13 | 
            +
            lib/striuct/subclassable/basic.rb
         | 
| 14 | 
            +
            lib/striuct/subclassable/safety.rb
         | 
| 15 | 
            +
            lib/striuct/subclassable/handy.rb
         | 
| 16 | 
            +
            lib/striuct/subclassable/hashlike.rb
         | 
| 17 | 
            +
            lib/striuct/subclassable/yaml.rb
         | 
| 18 | 
            +
            lib/striuct/subclassable/inner.rb
         | 
| 19 | 
            +
            lib/striuct/subclassable/eigen/frame.rb
         | 
| 20 | 
            +
            lib/striuct/subclassable/eigen/basic.rb
         | 
| 21 | 
            +
            lib/striuct/subclassable/eigen/constructor.rb
         | 
| 22 | 
            +
            lib/striuct/subclassable/eigen/safety.rb
         | 
| 23 | 
            +
            lib/striuct/subclassable/eigen/handy.rb
         | 
| 24 | 
            +
            lib/striuct/subclassable/eigen/macro.rb
         | 
| 25 | 
            +
            lib/striuct/subclassable/eigen/inner.rb
         | 
| 14 26 | 
             
            test/test_helper.rb
         | 
| 15 27 | 
             
            test/test_striuct.rb
         | 
| 28 | 
            +
            example/example.rb
         | 
| 29 | 
            +
            example/benchmarks.rb
         | 
| 30 | 
            +
            example/see_trace.rb
         | 
    
        data/README.ja.rdoc
    CHANGED
    
    | @@ -6,79 +6,82 @@ | |
| 6 6 |  | 
| 7 7 | 
             
            == DESCRIPTION
         | 
| 8 8 |  | 
| 9 | 
            -
             | 
| 9 | 
            +
            Struct以上の手軽さで扱える、Structより堅いコンテナを目指しています。
         | 
| 10 10 |  | 
| 11 | 
            -
             | 
| 12 | 
            -
            でもそうやってStruct | 
| 11 | 
            +
            メンバ名にチェックがかかる&一つの新しいクラスとして扱えるStructは、場面によってはHashよりも好ましい事があるかと思います。
         | 
| 12 | 
            +
            でもそうやってStructを使うぐらいなわけだから、値の方にもある程度のチェックをかけたいと思う事が多くありませんか?
         | 
| 13 13 |  | 
| 14 14 | 
             
            RubyのStructを愛しつつも、こういった部分をなんとかしたいと感じている方へお勧めします。
         | 
| 15 15 |  | 
| 16 16 | 
             
            1. ノーガードで参照を付けられるのがおっかないときもある
         | 
| 17 17 | 
             
            2. かといって、型チェックしか出来ないようじゃRubyのメリットが死ぬんではなかろうか
         | 
| 18 18 | 
             
            3. メンバ名でフツーのメソッド名を上書きしかねないのもおっかない
         | 
| 19 | 
            -
            4.  | 
| 20 | 
            -
            5.  | 
| 19 | 
            +
            4. 最初に代入したオブジェクトのクラスで固定したい(これは無いか)
         | 
| 20 | 
            +
            5. どうせなら、チェックだけじゃなくキャストなりやらせたものを参照したい
         | 
| 21 21 | 
             
            6. メンバによっては標準値も定義したい
         | 
| 22 | 
            +
            7. Hashとの親和性を高くしたい
         | 
| 23 | 
            +
            8. メンバ名にaliasかけたいけど、alias_methodだけだと添え字アクセス出来なくて歯がゆい
         | 
| 24 | 
            +
            9. 構造体クラスでも継承を使った上で、更にメンバ追加がしたい
         | 
| 22 25 |  | 
| 23 26 | 
             
            == FEATURES
         | 
| 24 27 |  | 
| 25 28 | 
             
            * メンバ毎に、参照条件を簡単に定義できます。
         | 
| 26 | 
            -
            *  | 
| 29 | 
            +
            * 型チェックではなく式チェックなので、動的型の良さを殺しません
         | 
| 27 30 | 
             
            * Proc(lambda)やMethod等 を使うことで、さらに柔軟なチェックが可能です
         | 
| 28 | 
            -
            *  | 
| 29 | 
            -
            *  | 
| 30 | 
            -
            * 構造体としてのメンバ追加時、Ruby | 
| 31 | 
            -
            *  | 
| 31 | 
            +
            * どれか一つの構造体で最初に代入したオブジェクトのクラスに沿うようなメンバを作れます。
         | 
| 32 | 
            +
            * 参照直前に、ちょっとした処理を加える事も可能です
         | 
| 33 | 
            +
            * 構造体としてのメンバ追加時、Rubyの既存メソッドと干渉しないかを指定レベル別にチェック出来ます。
         | 
| 34 | 
            +
            * 違和感のない継承利用
         | 
| 35 | 
            +
            * なるべくStructの心地よい操作感を残したまま機能追加をしています。
         | 
| 32 36 | 
             
            * 既存クラスやメソッドの上書き等を(勝手には)しない、控えめな名前空間
         | 
| 33 | 
            -
            *  | 
| 37 | 
            +
            * Pure Ruby
         | 
| 34 38 |  | 
| 35 39 | 
             
            == SYNOPSIS
         | 
| 36 40 |  | 
| 37 41 | 
             
            * setup
         | 
| 38 42 | 
             
                require 'striuct'
         | 
| 39 43 |  | 
| 40 | 
            -
            *  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            +
            * 2つの名前空間をお借りしますが、どっちも同じクラスを指します
         | 
| 45 | 
            +
                Striuct
         | 
| 46 | 
            +
                StrictStruct
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            === Struct+ "Safety"
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            ==== 基本的な使い方
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            * memberというクラスマクロを使うことで構造体のメンバを定義できます。
         | 
| 53 | 
            +
              引数2以降に、参照するための「条件」を渡して下さい。
         | 
| 54 | 
            +
              何も条件を渡さなければ、Struct同様ノーチェックです。
         | 
| 44 55 | 
             
                class User < Striuct.new
         | 
| 45 | 
            -
                  member :id, | 
| 46 | 
            -
                  member : | 
| 47 | 
            -
                  member : | 
| 48 | 
            -
                  member :name, /\A\w+\z/, /\A\w+ \w+\z/
         | 
| 56 | 
            +
                  member :id,   Integer
         | 
| 57 | 
            +
                  member :age,  (20..140)
         | 
| 58 | 
            +
                  member :name, OR(/\A\w+\z/, /\A\w+ \w+\z/)
         | 
| 49 59 | 
             
                end
         | 
| 50 60 |  | 
| 51 | 
            -
                #  | 
| 52 | 
            -
                user = User.new 128381,  | 
| 61 | 
            +
                # pass
         | 
| 62 | 
            +
                user = User.new 128381, 20
         | 
| 53 63 |  | 
| 54 | 
            -
                #  | 
| 64 | 
            +
                # pass
         | 
| 55 65 | 
             
                user.age = 30
         | 
| 56 | 
            -
                user | 
| 66 | 
            +
                user[2] = 'taro yamada'
         | 
| 57 67 |  | 
| 58 | 
            -
                #  | 
| 68 | 
            +
                # fail
         | 
| 59 69 | 
             
                user[:id] = 10.0
         | 
| 60 | 
            -
                user[1] = 'Tokyo-to'
         | 
| 61 70 | 
             
                user.age = 19
         | 
| 62 | 
            -
                user | 
| 71 | 
            +
                user[2] = nil
         | 
| 63 72 |  | 
| 64 | 
            -
             
         | 
| 65 | 
            -
            * リンク貼る時どれだけ注意しても、その後参照先のオブジェクトがぶっ壊れる可能性は残りますよね。
         | 
| 66 | 
            -
              これは致し方無いと思うので、チェックだけでも簡単にできるようにしています。
         | 
| 67 | 
            -
                user.strict? #=> true
         | 
| 68 | 
            -
                user.address.clear
         | 
| 69 | 
            -
                user.strict? #=> false
         | 
| 70 73 |  | 
| 71 | 
            -
            *  | 
| 74 | 
            +
            * 更に柔軟なチェッカが必要であれば関数的なオブジェクトを使って下さい。
         | 
| 72 75 | 
             
              この時Proc(lambda)を構造体インスタンスのコンテキストで評価する為、他のメンバと連携したチェックも簡単です。
         | 
| 73 76 | 
             
                module Game
         | 
| 74 77 | 
             
                  class Character
         | 
| 75 78 | 
             
                  end
         | 
| 76 79 |  | 
| 77 80 | 
             
                  class DB < Striuct.new
         | 
| 78 | 
            -
                    member :monsters, | 
| 79 | 
            -
                    member :characters,  | 
| 81 | 
            +
                    member :monsters,   ->list{(list - characters).empty?}
         | 
| 82 | 
            +
                    member :characters, GENERICS(Character)
         | 
| 80 83 | 
             
                  end
         | 
| 81 | 
            -
             | 
| 84 | 
            +
             | 
| 82 85 | 
             
                  monster = Character.new
         | 
| 83 86 | 
             
                  db = DB.new
         | 
| 84 87 |  | 
| @@ -89,17 +92,17 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい | |
| 89 92 | 
             
                  db.characters = [monster, Character.new]
         | 
| 90 93 |  | 
| 91 94 | 
             
                  # fail
         | 
| 92 | 
            -
                  db.monsters = [: | 
| 95 | 
            +
                  db.monsters = [:Character.new]
         | 
| 93 96 |  | 
| 94 97 | 
             
                  # pass
         | 
| 95 98 | 
             
                  db.monsters = [monster]
         | 
| 96 99 | 
             
                end
         | 
| 97 100 |  | 
| 98 101 | 
             
            * 構造体クラスのコンテキスト内だけで使える "inference" というメソッドの返り値を渡すと、
         | 
| 99 | 
            -
               | 
| 102 | 
            +
              最初に参照したオブジェクトのクラスが、以降全インスタンスでの参照条件となります。
         | 
| 100 103 | 
             
                class FlexibleContainer < Striuct.new
         | 
| 101 104 | 
             
                  member :anything, inference
         | 
| 102 | 
            -
                  member :number,  | 
| 105 | 
            +
                  member :number, Numeric, inference
         | 
| 103 106 | 
             
                end
         | 
| 104 107 |  | 
| 105 108 | 
             
                fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
         | 
| @@ -122,8 +125,51 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい | |
| 122 125 | 
             
                # fail
         | 
| 123 126 | 
             
                fc2.number = 1
         | 
| 124 127 |  | 
| 128 | 
            +
            ==== 意図しない名前干渉は避ける
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            * Structはこんな感じで、ノーガード上書き&メソッド定義出来ない物も無警告で進みます(object_id, __id__ なんかもそうですね)
         | 
| 131 | 
            +
                NoGuard = Struct.new :__send__, :'?  !'
         | 
| 132 | 
            +
                noguard = NoGuard.new false
         | 
| 133 | 
            +
                p noguard.__send__
         | 
| 134 | 
            +
                p noguard.methods.include?(:'?  !') # lost!!
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            * ということで、意図しない上書き等を防ぐために安全度を設定出来るようにしました。
         | 
| 137 | 
            +
              標準値は上から2番目の「:prevent」です。
         | 
| 138 | 
            +
                class SafetyNaming < Striuct.new
         | 
| 139 | 
            +
                  begin
         | 
| 140 | 
            +
                    member :__send__
         | 
| 141 | 
            +
                  rescue
         | 
| 142 | 
            +
                    p $!
         | 
| 143 | 
            +
                  end
         | 
| 144 | 
            +
                  
         | 
| 145 | 
            +
                  begin
         | 
| 146 | 
            +
                    member :'?  !'
         | 
| 147 | 
            +
                  rescue
         | 
| 148 | 
            +
                    p $!
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
                  
         | 
| 151 | 
            +
                  # ここで下げると、定義可能に
         | 
| 152 | 
            +
                  protect_level :struct
         | 
| 153 | 
            +
                  
         | 
| 154 | 
            +
                  member :__send__, :'?  !'
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            ==== この辺に関わる述語メソッド
         | 
| 158 | 
            +
             | 
| 159 | 
            +
            * valid? / acccept? / sufficient?   # そのメンバにその値が設定出来るか
         | 
| 160 | 
            +
            * conditionable?           # 条件式として受け入れ可能なオブジェクトか
         | 
| 161 | 
            +
            * inference?               # 定義時にinferenceを使った上で、一つも参照されていないか
         | 
| 162 | 
            +
            * restrict?                # そのメンバに参照条件がかけられているか
         | 
| 163 | 
            +
            * strict?                  # 今時点で全てのメンバが参照条件を満たしているか
         | 
| 164 | 
            +
            * secure?                  # インスタンスもクラスも変動することない状態で、インスタンスにfreezeがかかっているか
         | 
| 165 | 
            +
            * cname?                   # そのメンバ名は、今のprotect level下で望ましいものか
         | 
| 166 | 
            +
             | 
| 125 167 |  | 
| 126 | 
            -
             | 
| 168 | 
            +
            === Struct+ "Handy"
         | 
| 169 | 
            +
             | 
| 170 | 
            +
            ==== Flavor
         | 
| 171 | 
            +
             | 
| 172 | 
            +
            * memberマクロへブロックを渡しておくと、チェック後一処理加えた値を参照可能です。
         | 
| 127 173 | 
             
                class User2 < Striuct.new
         | 
| 128 174 | 
             
                  # 数字っぽければIntegerへ変換してから
         | 
| 129 175 | 
             
                  member :age, /\A\d+\z/, Numeric do |v|
         | 
| @@ -142,8 +188,11 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい | |
| 142 188 | 
             
                user2.age = '10' #=> 10(Fixnum)
         | 
| 143 189 |  | 
| 144 190 | 
             
                user2.name = 10 #=> :10(Symbol)
         | 
| 191 | 
            +
                user2.name = Class #=> :Class(Symbol)
         | 
| 192 | 
            +
             | 
| 193 | 
            +
            ==== Default
         | 
| 145 194 |  | 
| 146 | 
            -
            *  | 
| 195 | 
            +
            * defaultマクロを用いることで、メンバ毎に標準値を定義することが出来ます。
         | 
| 147 196 | 
             
                class User3 < Striuct.new
         | 
| 148 197 | 
             
                  member  :lank, Fixnum
         | 
| 149 198 | 
             
                  default :lank, 3
         | 
| @@ -153,44 +202,51 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい | |
| 153 202 | 
             
                user3 = User3.new
         | 
| 154 203 | 
             
                user3.lank #=> 3
         | 
| 155 204 |  | 
| 156 | 
            -
            *  | 
| 157 | 
            -
               | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
             | 
| 161 | 
            -
               user3.name = nil
         | 
| 162 | 
            -
               user3.assign? :name #=> true
         | 
| 205 | 
            +
            * 「意図的なnil」との区別を付けられます。
         | 
| 206 | 
            +
                user3.name  #=> nil
         | 
| 207 | 
            +
                user3.assign? :name #=> false
         | 
| 208 | 
            +
                user3.name = nil
         | 
| 209 | 
            +
                user3.assign? :name #=> true
         | 
| 163 210 |  | 
| 164 | 
            -
             | 
| 165 | 
            -
                NoGuard = Struct.new :__send__, :'?  !'
         | 
| 166 | 
            -
                noguard = NoGuard.new false
         | 
| 167 | 
            -
                p noguard.__send__
         | 
| 168 | 
            -
                p noguard.methods.include?(:'?  !') # lost!!
         | 
| 211 | 
            +
            ==== Alias
         | 
| 169 212 |  | 
| 170 | 
            -
            *  | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
                  begin
         | 
| 174 | 
            -
                    member :__send__
         | 
| 175 | 
            -
                  rescue
         | 
| 176 | 
            -
                    p $!
         | 
| 177 | 
            -
                  end
         | 
| 178 | 
            -
                  
         | 
| 179 | 
            -
                  begin
         | 
| 180 | 
            -
                    member :'?  !'
         | 
| 181 | 
            -
                  rescue
         | 
| 182 | 
            -
                    p $!
         | 
| 183 | 
            -
                  end
         | 
| 184 | 
            -
                  
         | 
| 185 | 
            -
                  # ここで下げると、定義可能に
         | 
| 186 | 
            -
                  protect_level :struct
         | 
| 187 | 
            -
                  
         | 
| 188 | 
            -
                  member :__send__, :'?  !'
         | 
| 213 | 
            +
            * メンバ名を付与出来ます。(標準Structだと、添字アクセス可能にしたりするのが面倒。)
         | 
| 214 | 
            +
                class User3
         | 
| 215 | 
            +
                  alias_member :position, :lank
         | 
| 189 216 | 
             
                end
         | 
| 217 | 
            +
                
         | 
| 218 | 
            +
                user3.lank.equal? user3.position #=> true
         | 
| 219 | 
            +
                user3[:lank].equal? user3[:position] #=> true
         | 
| 220 | 
            +
                user3[:position] = 4
         | 
| 221 | 
            +
                user3.lank  #=> 4
         | 
| 222 | 
            +
             | 
| 223 | 
            +
            ==== Inherit
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            * (writing...)
         | 
| 190 226 |  | 
| 191 | 
            -
             | 
| 192 | 
            -
                Sth1 = Striuct.new :id, :last_name, :family_name, :address, :age
         | 
| 227 | 
            +
            ==== Lock
         | 
| 193 228 |  | 
| 229 | 
            +
            * (writing...)
         | 
| 230 | 
            +
             | 
| 231 | 
            +
            ==== New Constructors
         | 
| 232 | 
            +
             | 
| 233 | 
            +
            * Subclass.define は、生成時から先オブジェクトを変える必要が無いケースで使います。
         | 
| 234 | 
            +
              * ブロックパラメータに新しいインスタンスがわたり、またこれが返り値となります
         | 
| 235 | 
            +
              * すべてのメンバがアサイン済みかをチェックします
         | 
| 236 | 
            +
              * ブロックを抜ける直前に、全て問題ない値かチェックします(オプション指定可)
         | 
| 237 | 
            +
              * ブロックを抜ける直前に、全てlockをかけます(オプション指定可)
         | 
| 238 | 
            +
                  user3 = User3.define do |r|
         | 
| 239 | 
            +
                    r.lank = 10
         | 
| 240 | 
            +
                    r.name = 'foo'
         | 
| 241 | 
            +
                  end
         | 
| 242 | 
            +
             | 
| 243 | 
            +
            * Subclass.[](load_pairs) は、HashなりHashっぽいものから作る時用です。
         | 
| 244 | 
            +
              # Struct.[] の仕様とは異なります。
         | 
| 245 | 
            +
                user3 = User3[lank:10, name: 'foo']
         | 
| 246 | 
            +
             | 
| 247 | 
            +
            === Structの良さは活かしたまま
         | 
| 248 | 
            +
             | 
| 249 | 
            +
            * 基本的にはStruct使い(?)が余り違和感を感じ無いようにしたつもりです。
         | 
| 194 250 | 
             
                Sth2 = Striuct.new do
         | 
| 195 251 | 
             
                  def my_special_method
         | 
| 196 252 | 
             
                  end
         | 
| @@ -198,21 +254,24 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい | |
| 198 254 |  | 
| 199 255 | 
             
                Sth2.new.respond_to?(:my_special_method) #=> true
         | 
| 200 256 |  | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 257 | 
            +
            === Hashとお近づきに
         | 
| 258 | 
            +
             | 
| 259 | 
            +
            * どちらかというとStructはHashよりArray寄りな感じを受けるのですが、個人的にHash的な動きをしてくれると嬉しい事の方が多く感じます。
         | 
| 260 | 
            +
              ということで、やり過ぎない範囲でHashっぽく使えるように調整しています。
         | 
| 204 261 |  | 
| 205 | 
            -
            *  | 
| 206 | 
            -
             | 
| 262 | 
            +
            * Hashへの変換も一発です。
         | 
| 263 | 
            +
                user3.to_h #=> {:lank=>3, :name=>nil}
         | 
| 207 264 |  | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 265 | 
            +
            == Note
         | 
| 266 | 
            +
             | 
| 267 | 
            +
            * 現状、このReadme含めてドキュメントは殆ど更新出来ていません。
         | 
| 268 | 
            +
              0.2.0 までにはなんとかしたい
         | 
| 210 269 |  | 
| 211 270 | 
             
            == REQUIREMENTS
         | 
| 212 271 |  | 
| 213 272 | 
             
            === Ruby
         | 
| 214 | 
            -
             | 
| 215 | 
            -
            * 1.9.2
         | 
| 273 | 
            +
             | 
| 274 | 
            +
            * Ruby 1.9.2 and later (tested 1.9.2, 1.9.3)
         | 
| 216 275 |  | 
| 217 276 | 
             
            == INSTALL
         | 
| 218 277 |  |