card 1.105.0 → 1.105.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/card/director/card_class.rb +17 -14
  4. data/lib/card/fetch/card_class.rb +19 -13
  5. data/lib/card/name.rb +3 -3
  6. data/lib/card/query.rb +8 -5
  7. data/lib/card/set/abstract.rb +1 -0
  8. data/lib/card/set/format/abstract_format/wrapper.rb +0 -1
  9. data/lib/card/set/format/abstract_format.rb +4 -3
  10. data/lib/card/set/format.rb +46 -20
  11. data/lib/card/set/helpers.rb +49 -36
  12. data/lib/card/set/registrar.rb +3 -5
  13. data/lib/card/set/required_field.rb +3 -2
  14. data/lib/card/set/type.rb +1 -0
  15. data/lib/card/set.rb +67 -21
  16. data/lib/card.rb +30 -12
  17. data/lib/cardio/command/custom.rb +1 -0
  18. data/lib/cardio/command/rake_command.rb +1 -1
  19. data/lib/cardio/command/rspec_command/parser.rb +7 -4
  20. data/lib/cardio/generators.rb +1 -1
  21. data/lib/cardio/mod/class_methods.rb +2 -2
  22. data/lib/cardio/mod/dirs.rb +1 -1
  23. data/lib/cardio/mod/eat/edibles.rb +21 -1
  24. data/lib/cardio/mod/eat.rb +4 -2
  25. data/lib/cardio/mod/modfile_api.rb +2 -2
  26. data/lib/cardio/mod/sow.rb +16 -16
  27. data/lib/cardio/mod.rb +30 -48
  28. data/lib/cardio/railtie.rb +3 -3
  29. data/lib/generators/mod/mod_generator.rb +5 -5
  30. data/mod/core/lib/tasks/card/mod.rake +5 -2
  31. data/mod/core/lib/tasks/card/seed.rake +6 -4
  32. data/mod/core/lib/tasks/card.rake +8 -4
  33. data/mod/core/set/all/states.rb +8 -2
  34. metadata +6 -8
  35. data/mod/core/lib/tasks/card/assets.rake +0 -17
  36. data/mod/core/lib/tasks/card/create.rake +0 -81
  37. /data/mod/core/{locales → config/locales}/de.yml +0 -0
  38. /data/mod/core/{locales → config/locales}/en.yml +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c27e643a91315f8bfd6fc3fba7c744848203ba221637e03808a35f7d21869bec
4
- data.tar.gz: 6792846d1b8853ab5681db115b60a5fdb0753771b90af28572b00208ef1a147d
3
+ metadata.gz: 7d1c8cf4b2e9416f3e17e107de3651e51957b9bb0f8bd9a32dfb7c9e5ffcfe5e
4
+ data.tar.gz: ea4bf60694b93994f9fd8e626fe2dd6bf0860ce1e270e533066b42d3e98c0f39
5
5
  SHA512:
6
- metadata.gz: 736423e17a671d1cdd5281fea9ba90ceaf6f37ab55bcbe52ac5ef8f0c91649a93d9e6e38d24fd841dba3966379162fdd55e0a3b71be7bab9fb7697c40fafef1b
7
- data.tar.gz: 4e6de86094dfad8e899383d005bb78fa8d9a21d0e73f4d2799c49db683b8a08a37d711fb45be7325240fb77d0a284f9539206f35ccb107e29bdc6766fc1470d6
6
+ metadata.gz: 65ff19795cd4a020bd67bf08d35d5eef95c3b904bc70fd2fe94eee219c5e34e4e77b29868302f98069d3fc2877c7cf9f69bffc5193bdffec337925a57997b1d3
7
+ data.tar.gz: 40ada7a7227dd40ae2d8edb9a23aa4a6c4777c505a73f1a39e2ed2ad9ce741078e1645ac995de6ad8c509bfb94f11f02dec78d8906ad465cdae09ecc444cbab1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.15.0
1
+ 0.15.1
@@ -16,35 +16,38 @@ class Card
16
16
 
17
17
  # The ensure methods are use to make sure a card exists and can be used when you're
18
18
  # unsure as to whether it already does. It's arguments are largely the same as
19
- # those used by Card.create and @card.update with the important exception of
20
- # `conflict`.
21
-
19
+ # those used by {#create Card#create} and {Director::All#update @card.update} with
20
+ # the important exception of `conflict`.
21
+ #
22
22
  # The conflict argument takes one of three values:
23
- # - defer: let existing card stay as it is
24
- # - default: update existing card if it is "pristine" (has not been edited by
25
- # anyone other than Decko Bot)
26
- # - override: update existing card
27
-
23
+ #
24
+ # - **defer**: let existing card stay as it is
25
+ # - **default**: update existing card if it is "pristine" (meaning it has not
26
+ # been edited by anyone other than Decko Bot)
27
+ # - **override**: update existing card
28
+ #
28
29
  # If the options specify a codename and the name is already in use, things get a
29
30
  # little more involved. (Note: we MUST ensure that a card with the codename exists!)
30
-
31
- # If the conflict setting is "defer":
31
+ #
32
+ # If the conflict setting is "**defer**":
32
33
  #
33
34
  # - if the _codename_ is NOT already in use, we create a new card with an
34
35
  # altered name
35
36
  # - otherwise we do nothing.
36
37
  #
37
- # If the conflict setting is "default":
38
+ # If the conflict setting is "**default**":
39
+ #
38
40
  # - if the _codename_ is NOT already in use:
39
41
  # - if the card using the name we want is pristine, we update that card
40
42
  # - otherwise we create a new card with an altered name
41
- # - if the _codename IS already in use
43
+ # - if the _codename_ IS already in use
42
44
  # - if the card with the codename is pristine, we update everything but the
43
45
  # name (which is used by another card)
44
46
  # - otherwise we do nothing
45
47
  #
46
- # If the conflict setting is "override":
47
- # - if the _codename is NOT already in use, we update the existing card with the
48
+ # If the conflict setting is "**override**":
49
+ #
50
+ # - if the _codename_ is NOT already in use, we update the existing card with the
48
51
  # name.
49
52
  # - otherwise we alter the card withe the conflicting name and update the card
50
53
  # with the codename.
@@ -1,29 +1,32 @@
1
1
  class Card
2
2
  class Fetch
3
- # = Card#fetch
4
- #
5
- # A multipurpose retrieval operator that integrates caching, database lookups,
3
+ # A multipurpose retrieval system that integrates caching, database lookups,
6
4
  # and "virtual" card construction
7
5
  module CardClass
8
6
  # Look for cards in
9
- # * cache
10
- # * database
11
- # * virtual cards
7
+ # * cache
8
+ # * database
9
+ # * virtual cards
12
10
  #
13
11
  # @param args [Integer, String, Card::Name, Symbol, Array]
14
12
  # Initials args must be one or more "marks," which uniquely idenfify cards:
13
+ #
14
+ #
15
15
  # 1. a name/key. (String or Card::Name)
16
16
  # 2. a numeric id. Can be (a) an Integer or (b) a String with an integer
17
17
  # prefixed with a tilde, eg "~1234"
18
18
  # 3. a codename. Can be (a) a Symbol or (b) a String with a colon prefix,
19
19
  # eg :mycodename
20
+ #
20
21
  # If you pass more then one mark or an array of marks they get joined with a '+'.
21
22
  # The final argument can be a Hash to set the following options
22
- # :skip_virtual Real cards only
23
- # :skip_modules Don't load Set modules
24
- # :look_in_trash Return trashed card objects
25
- # :local_only Use only local cache for lookup and storing
26
- # new: { opts for Card#new } Return a new card when not found
23
+ #
24
+ # :skip_virtual Real cards only
25
+ # :skip_modules Don't load Set modules
26
+ # :look_in_trash Return trashed card objects
27
+ # :local_only Use only local cache for lookup and storing
28
+ # new: { opts for Card#new } Return a new card when not found
29
+ #
27
30
  # @return [Card]
28
31
  def fetch *args
29
32
  f = Fetch.new(*args)
@@ -32,9 +35,9 @@ class Card
32
35
  Card.new name: "card id out of range: #{f.mark}"
33
36
  end
34
37
 
35
- # fetch only real (no virtual) cards
38
+ # a shortcut for fetch that returns only real cards (no virtuals)
36
39
  #
37
- # @param mark - see #fetch
40
+ # @param mark [various] - see {#fetch}
38
41
  # @return [Card]
39
42
  def [] *mark
40
43
  fetch(*mark, skip_virtual: true)
@@ -62,6 +65,9 @@ class Card
62
65
  # ATTRIBUTE FETCHING
63
66
  # The following methods optimize fetching of specific attributes
64
67
 
68
+ # numerical card id
69
+ # @params cardish [various] interprets integers as id, symbols as codename, etc
70
+ # @return [Integer]
65
71
  def id cardish
66
72
  case cardish
67
73
  when Integer then cardish
data/lib/card/name.rb CHANGED
@@ -5,10 +5,10 @@
5
5
  require "cardname"
6
6
 
7
7
  class Card
8
- # The Cardname class provides generalized of Card naming patterns
9
- # (compound names, key-based variants, etc)
8
+ # The {Cardname} class provides generalized of Card naming patterns (compound names,
9
+ # key-based variants, etc) and can be used independently of Card objects.
10
10
  #
11
- # Card::Name adds support for deeper card integration
11
+ # {Card::Name} adds support for deeper integration with Card objects
12
12
  class Name < Cardname
13
13
  include NameVariants
14
14
 
data/lib/card/query.rb CHANGED
@@ -7,8 +7,8 @@ class Card
7
7
  # frequently used directly in code.
8
8
  #
9
9
  # Query "statements" (objects, really) are made in CQL (Card Query
10
- # Language). Because CQL is used by Sharks, the primary language
11
- # documentation is on decko.org. (https://decko.org/CQL_Syntax). Note that the
10
+ # Language). Because CQL is used by Sharks, [the primary CQL Syntax documentation is
11
+ # on decko.org](https://decko.org/CQL_Syntax). Note that the
12
12
  # examples there are in JSON, like Search card content, but statements in
13
13
  # Card::Query are in ruby form.
14
14
  #
@@ -17,9 +17,11 @@ class Card
17
17
  # CQL statement interpretation.
18
18
  #
19
19
  # The most common way to use Card::Query is as follows:
20
+ #
20
21
  # list_of_cards = Card::Query.run(statement)
21
22
  #
22
23
  # This is equivalent to:
24
+ #
23
25
  # query = Card::Query.new(statement)
24
26
  # list_of_cards = query.run
25
27
  #
@@ -32,7 +34,8 @@ class Card
32
34
  # - @subqueries - a list of other queries nested within this one
33
35
  #
34
36
  # Each condition is either a SQL-ready string (boo) or an Array in this form:
35
- # [ field_string_or_sym, Card::Value::Query object ]
37
+ #
38
+ # [field_string_or_sym, (Card::Value::Query object)]
36
39
  module Query
37
40
  require "card/query/clause"
38
41
  require "card/query/card_query"
@@ -48,8 +51,8 @@ class Card
48
51
  # their values are translated fairly directly into SQL-safe values.
49
52
  # (These are referred to as "properties" in CQL documentation. Need to
50
53
  # reconcile #EFM)
51
- basic: %i[id name key type_id content left_id right_id
52
- creator_id updater_id codename read_rule_id],
54
+ basic: %i[id name key type_id content left_id right_id codename read_rule_id
55
+ created_at updated_at creator_id updater_id ],
53
56
  # "Relational" values can involve tying multiple queries together
54
57
  relational: %i[type
55
58
  part left right
@@ -1,5 +1,6 @@
1
1
  class Card
2
2
  module Set
3
+ # Base class for abstract sets defined in {Card::Set set modules}
3
4
  class Abstract < Pattern::Base
4
5
  end
5
6
  end
@@ -1,7 +1,6 @@
1
1
  class Card
2
2
  module Set
3
3
  module Format
4
- # AbstractFormat extends all format classes
5
4
  module AbstractFormat
6
5
  # The Wrapper module provides an API to define wrap methods.
7
6
  # It is available in all formats.
@@ -3,9 +3,10 @@
3
3
  class Card
4
4
  module Set
5
5
  module Format
6
- # AbstractFormat manages the basic format API, including API to define a {#view}.
7
- # Whenever you create a format block in a set module in a {Cardio::Mod mod}, you
8
- # create a format module that is extended with AbstractFormat.
6
+ # AbstractFormat manages the DSL for defining {#view views}.
7
+ #
8
+ # Whenever you create a {Format format} block in a {Cardio::Set set module},
9
+ # you create a format module that is extended with AbstractFormat.
9
10
  module AbstractFormat
10
11
  include ViewOpts
11
12
  include ViewDefinition
@@ -2,33 +2,58 @@
2
2
 
3
3
  class Card
4
4
  module Set
5
- # This document explains how to use format blocks within {Cardio::Mod mods}. To make
6
- # use of it, you will need to understand both {Cardio::Mod mods} and {Card::Set sets}.
5
+ # Card::Set::Format is responsible for handling `format` blocks within the set module
6
+ # DSL, which is used in {Cardio::Mod Set module} files found in {Cardio::Mod mods'}
7
+ # set directories. Monkeys use the DSL to define views that apply to specific sets of
8
+ # cards in specific formats. The views can then be
9
+ # used by Monkeys in code and by Sharks via the UI.
7
10
  #
8
- # Within a card mod, you can define format blocks like the following:
11
+ # For example, imagine you have a set module file in `mod/mymod/type/my_type.rb`.
12
+ # There you can define a view like this:
9
13
  #
10
14
  # format :html do
11
- # def beethoven
15
+ # view :hello do
16
+ # greeting
17
+ # end
18
+ # end
19
+ #
20
+ # {AbstractFormat#view Learn more about defining views}
21
+ #
22
+ # This view will now be available to MyType cards in HTML -- but not in other formats.
23
+ # Similarly, you can define other methods in format blocks:
24
+ #
25
+ # format :html do
26
+ # def greeting
12
27
  # :rocks
13
28
  # end
14
29
  # end
15
30
  #
16
- # The magic that happens here is that the method #beethoven is now applicable (and
17
- # available) _only_ to the cards in the set specified by the mod, and only when
18
- # the card is rendering a view in the HTML format.
31
+ # The magic that happens here is that the method #greeting is now applicable (and
32
+ # available) _only_ to the cards in the {Card::Set set} specified by the mod, and
33
+ # only when rendering a view of the card in the HTML format. {Card::Format Learn
34
+ # more about formats}.
19
35
  #
20
- # If you care, you can certainly learn about how all this works. How the set module
21
- # creates a module that looks something like `Card::Set::Type::MyType::HtmlFormat`.
22
- # How the format object for a given card in the set includes this module dynamically
23
- # when it's initialized. And so on...
36
+ # So if, for example, I had a card "MyCard" with the type "MyType", the following
37
+ # should use the method above:
24
38
  #
25
- # But as monkeys, we don't usually think about all that much, because we work in
39
+ # ````
40
+ # "MyCard".card.format(:html).greeting
41
+ # ````
42
+ #
43
+ # ...but if the card had a different type, or if I tried to use the method in, say,
44
+ # the JSON format, this #beethoven method wouldn't be available.
45
+ #
46
+ # Under the hood, the DSL creates a ruby module that looks something like
47
+ # `Card::Set::Type::MyType::HtmlFormat`. This module will then be dynamically included
48
+ # in HTML format objects for MyCard.
49
+ #
50
+ # As monkeys, we don't usually think about all that much, because we work in
26
51
  # the set module space, which lets us focus on the card patterns.
27
52
  #
28
53
  # Speaking of which, there are a few key patterns to be aware of:
29
54
  #
30
55
  # 1. Just as in {Card::Set sets}, format methods for narrower sets will override
31
- # format methods for more general sets. So if a #beethoven method is defined
56
+ # format methods for more general sets. So if a #greeting method is defined
32
57
  # for all cards and again for a specific card type, then the type method will
33
58
  # override the all method when both apply.
34
59
  # 2. Similarly, specific formats inherit from more general formats, and all formats
@@ -36,27 +61,28 @@ class Card
36
61
  # will define methods on the base format class.
37
62
  #
38
63
  # format do
39
- # def haydn
40
- # :sucks
64
+ # def farewell
65
+ # "goodbye"
41
66
  # end
42
67
  # end
43
68
  #
44
69
  # 3. It is possible to use super to refer to overridden methods. For example
45
70
  #
46
71
  # format :html do
47
- # def haydn
72
+ # def goodbye
48
73
  # "<em>#{super}</em>"
49
74
  # end
50
75
  # end
51
76
  #
52
77
  # Note: Set precedence has a higher priority than Format precedence.
53
78
  #
54
- # 4. {#view} and {#before} can both be called outside of a format block. They will
55
- # be defined on the base format.
56
- #
57
- # 5. Some very powerful API calls (including {AbstractFormat#view view} and
79
+ # 4. Some very powerful API calls (including {AbstractFormat#view view} and
58
80
  # {AbstractFormat#before before}) are defined in {AbstractFormat}. These methods are
59
81
  # always available in format blocks.
82
+ #
83
+ # 5. {#view} and {#before}, however, can ALSO both be called outside of a format
84
+ # block. They will be defined on the base format.
85
+ #
60
86
  module Format
61
87
  require "card/set/format/haml_paths"
62
88
  require "card/set/format/abstract_format"
@@ -1,42 +1,32 @@
1
1
  class Card
2
2
  module Set
3
+ # These helper methods provide easy access to metadata, such as information about
4
+ # the set modified by a module. These methods are seldom used by Monkeys; they are
5
+ # primarily Platypus tools.
3
6
  module Helpers
4
7
  SET_PATTERN_TEST_REGEXP = /^(?<pattern>\w+)_set\?$/
5
8
 
9
+ # @return [String] short name of card module. For example, returns Type::User for
10
+ # Card::Set::Type::User
6
11
  def shortname
7
12
  first = 2 # shortname eliminates Card::Set
8
13
  last = first + num_set_parts(pattern_code)
9
14
  set_name_parts[first..last].join "::"
10
15
  end
11
16
 
12
- def underscore
17
+ # @return [String] name of card module with underscores. For example, returns
18
+ # Card__Set__Type__User for Card::Set::Type::User
19
+ def underscored_name
13
20
  shortname.tr(":", "_").underscore
14
21
  end
15
22
 
16
- def num_set_parts pattern_code
17
- return 1 if pattern_code == :abstract
18
-
19
- Pattern.find(pattern_code).anchor_parts_count
20
- end
21
-
22
- def set_format_type_key
23
- @set_format_type_key ||= :"#{set_type_key}_format"
24
- end
25
-
26
- def set_type_key
27
- if all_set?
28
- :base
29
- elsif abstract_set?
30
- :abstract
31
- else
32
- :nonbase
33
- end
34
- end
35
-
23
+ # @return [Array] list of strings of parts of set module's name
24
+ # Eg, returns ["Card", "Set", "Type", "User"] for Card::Set::Type::User
36
25
  def set_name_parts
37
26
  @set_name_parts ||= name.split "::"
38
27
  end
39
28
 
29
+ # @return [Symbol] codename associated with set's pattern. Eg :type, :right, etc
40
30
  def pattern_code
41
31
  @pattern_code ||= set_name_parts[2].underscore.to_sym
42
32
  end
@@ -50,6 +40,8 @@ class Card
50
40
  end
51
41
  end
52
42
 
43
+ # @return [true/false]
44
+ # handles all_set?, abstract_set?, type_set?, etc.
53
45
  def respond_to_missing? method_name, _include_private=false
54
46
  method_name.match? SET_PATTERN_TEST_REGEXP
55
47
  end
@@ -64,21 +56,6 @@ class Card
64
56
  end
65
57
  end
66
58
 
67
- def test_set
68
- # rubocop:disable Lint/Eval
69
- ::Card::Set::Self.const_remove_if_defined :TestSet
70
- eval <<-RUBY, binding, __FILE__, __LINE__ + 1
71
- class ::Card::Set::Self
72
- module TestSet
73
- extend Card::Set
74
- include_set #{name}
75
- end
76
- end
77
- RUBY
78
- ::Card::Set::Self::TestSet
79
- # rubocop:enable Lint/Eval
80
- end
81
-
82
59
  def format_modules format_sym, test: true
83
60
  if base_format_modules?
84
61
  [format_module(format_sym)]
@@ -95,6 +72,36 @@ class Card
95
72
 
96
73
  private
97
74
 
75
+ # @return [Symbol] base_format,
76
+ def set_format_type_key
77
+ @set_format_type_key ||= :"#{set_type_key}_format"
78
+ end
79
+
80
+ def set_type_key
81
+ if all_set?
82
+ :base
83
+ elsif abstract_set?
84
+ :abstract
85
+ else
86
+ :nonbase
87
+ end
88
+ end
89
+
90
+ def test_set
91
+ # rubocop:disable Lint/Eval
92
+ ::Card::Set::Self.const_remove_if_defined :TestSet
93
+ eval <<-RUBY, binding, __FILE__, __LINE__ + 1
94
+ class ::Card::Set::Self
95
+ module TestSet
96
+ extend Card::Set
97
+ include_set #{name}
98
+ end
99
+ end
100
+ RUBY
101
+ ::Card::Set::Self::TestSet
102
+ # rubocop:enable Lint/Eval
103
+ end
104
+
98
105
  def base_format_modules?
99
106
  !set_format_type_key || set_format_type_key == :base_format
100
107
  end
@@ -107,6 +114,12 @@ class Card
107
114
  format_class = Card::Format.format_class format: format_sym
108
115
  Card::Set.modules[set_format_type_key][format_class][shortname] || []
109
116
  end
117
+
118
+ def num_set_parts pattern_code
119
+ return 1 if pattern_code == :abstract
120
+
121
+ Pattern.find(pattern_code).anchor_parts_count
122
+ end
110
123
  end
111
124
  end
112
125
  end
@@ -3,7 +3,7 @@
3
3
  class Card
4
4
  module Set
5
5
  # the set loading process has two main phases:
6
-
6
+ #
7
7
  # 1. Definition: interpret each set file, creating/defining set and
8
8
  # set_format modules
9
9
  # 2. Organization: have base classes include modules associated with the
@@ -72,10 +72,8 @@ class Card
72
72
 
73
73
  # makes sets ready for dynamic loading via #include_set_modules
74
74
  def register_set_of_type set_module, set_type
75
- mods = modules[set_type]
76
- key = set_module.shortname
77
- mods[key] ||= []
78
- mods[key] << set_module
75
+ list = modules[set_type][set_module.shortname] ||= []
76
+ list << set_module unless list.member? set_module
79
77
  end
80
78
 
81
79
  def process_base_format_modules base_format_modules
@@ -18,11 +18,12 @@ class Card
18
18
  end
19
19
 
20
20
  def parent_event_name
21
- [parent_set.underscore, "requires_field", field].join("__").to_sym
21
+ [parent_set.underscored_name, "requires_field", field].join("__").to_sym
22
22
  end
23
23
 
24
24
  def field_event_name action
25
- [field, "required_by", parent_set.underscore, "on", action].join("__").to_sym
25
+ [field, "required_by", parent_set.underscored_name, "on", action]
26
+ .join("__").to_sym
26
27
  end
27
28
 
28
29
  private
data/lib/card/set/type.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  class Card
2
2
  module Set
3
+ # Base class for type sets defined in {Card::Set set modules}
3
4
  class Type < Pattern::Base
4
5
  cattr_accessor :assignment
5
6
  self.assignment = {}
data/lib/card/set.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  class Card
4
- #
5
4
  # A _Set_ is a group of {Card Cards} to which _Rules_ may apply. Sets can be as
6
5
  # specific as a single card, as general as all cards, or anywhere in between.
7
6
  #
@@ -11,39 +10,86 @@ class Card
11
10
  # web interface and are thus documented at https://decko.org/rules.
12
11
  # - **Code rules** can be defined in a 'set module'.
13
12
  #
14
- # The {Cardio::Mod} docs explain how to create mods and set_modules. This page explains
15
- # how those modules become useful.
13
+ # ## Set Modules
14
+ #
15
+ # ### File structure
16
+ #
17
+ # Set modules specify views, events, and other methods for a given set of cards.
18
+ # They are defined in a {Cardio::Mod mod's} _set_ directory. For example, suppose
19
+ # you've created a mod called *biz*, your deck has Company cards, and you want to
20
+ # extend the behavior of those cards.
21
+ #
22
+ # You can add a set module like so:
23
+ #
24
+ # card generate set biz type company
25
+ #
26
+ # This will create the following two files:
27
+ #
28
+ # mod/biz/set/type/company.rb
29
+ # mod/biz/spec/set/type/company.rb
30
+ #
31
+ # If you would like to break this code into smaller files, you can extend this
32
+ # pattern into another directory, eg:
33
+ #
34
+ # mod/biz/set/type/company/foo.rb
35
+ # mod/biz/set/type/company/bar.rb
36
+ #
37
+ # The general pattern can be expressed as follows:
38
+ #
39
+ # DECKNAME/mod/MODNAME/set/SET_PATTERN/ANCHOR[/FREENAME].rb
16
40
  #
17
- # Suppose you have created a "mod" for managing your contacts called "contactmanager",
18
- # and it includes code that would apply to all +address cards here:
41
+ # **Note:** _the set module's filename connects it to the set, so both the set_pattern
42
+ # and the set_anchor must correspond to the codename of a card in the database to
43
+ # function correctly. For example, the type/company directory corresponds to the Set
44
+ # card named `:company+:type`. Both the :company and :type codenames must exist for this
45
+ # to work properly._
46
+ #
47
+ # ### Writing/Editing set modules
48
+ #
49
+ # A set module is mostly standard ruby, but the files are quite concise because
50
+ #
51
+ # 1. the set module's file location is used to autogenerate ruby module definitions
52
+ # 2. A DSL (Domain-Specific Language) makes common tasks easy.
53
+ #
54
+ # You can, for example, edit `mod/biz/set/type/company.rb`, and add _only_ the
55
+ # following code:
56
+ #
57
+ # def hello
58
+ # "world"
59
+ # end
19
60
  #
20
- # ./contactmanager/set/right/address.rb
61
+ # No further code is needed for this method to be available to cards with the type
62
+ # Company (as specified by the file's location). This code will automatically be added
63
+ # to a ruby module named `Card::Set::Type::Company`. That module is extended with the
64
+ # {Card::Set} module, giving it access to the set module DSL.
21
65
  #
22
- # Then, whenever you fetch or instantiate a +address card, the card will automatically
23
- # include code from that set module. In fact, it will include all the set modules
24
- # associated with sets of which it is a member.
66
+ # These important Card::Set subclasses explain more about the DSL
67
+ #
68
+ # - {Format} introduces format blocks
69
+ # - {Format::AbstractFormat} covers {Format::AbstractFormat#view view} definitions
70
+ # - {Event::Api} explains {Event::Api#event event} definitions
71
+ #
72
+ # ### Loading set modules
73
+ #
74
+ # Whenever you fetch or instantiate a card, the card will automatically
75
+ # include code from all the set modules associated with sets of which it is a member.
25
76
  #
26
77
  # For example, say you have a Plaintext card named 'Philipp+address', and you have set
27
78
  # files for the following sets:
28
79
  #
29
- # * all cards
30
- # * all Plaintext cards
31
- # * all cards ending in +address
80
+ # * all cards
81
+ # * all Plaintext cards
82
+ # * all cards ending in +address
32
83
  #
33
- # When you run this:
84
+ # When you run any of these:
34
85
  #
35
- # mycard = Card.fetch 'Philipp+address'
86
+ # mycard = Card.fetch "Philipp+address"
87
+ # mycard = "Philipp+address".card
88
+ # mycard = ["Philipp", "address"].card
36
89
  #
37
90
  # ...then mycard will include the set modules associated with each of those sets in the
38
91
  # above order.
39
92
  #
40
- # Note that the set module's filename connects it to the set, so both the set_pattern
41
- # and the set_anchor must correspond to the codename of a card in the database to
42
- # function correctly.
43
- #
44
- # A set module is "just ruby", but is generally quite concise because Card uses
45
- # a) the set module's file location to autogenerate ruby module names and
46
- # b) Card::Set to provide API for the most common set methods.
47
93
  #
48
94
  module Set
49
95
  include Event::Api