actionmailer 2.3.18 → 3.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionmailer might be problematic. Click here for more details.

Files changed (154) hide show
  1. data/CHANGELOG +13 -16
  2. data/README +39 -21
  3. data/lib/action_mailer/adv_attr_accessor.rb +14 -18
  4. data/lib/action_mailer/base.rb +437 -560
  5. data/lib/action_mailer/collector.rb +36 -0
  6. data/lib/action_mailer/delivery_methods.rb +86 -0
  7. data/lib/action_mailer/deprecated_api.rb +139 -0
  8. data/lib/action_mailer/mail_helper.rb +25 -13
  9. data/lib/action_mailer/old_api.rb +248 -0
  10. data/lib/action_mailer/quoting.rb +4 -2
  11. data/lib/action_mailer/railtie.rb +25 -0
  12. data/lib/action_mailer/railties/subscriber.rb +20 -0
  13. data/lib/action_mailer/test_case.rb +4 -6
  14. data/lib/action_mailer/test_helper.rb +0 -1
  15. data/lib/action_mailer/tmail_compat.rb +34 -0
  16. data/lib/action_mailer/version.rb +3 -3
  17. data/lib/action_mailer.rb +25 -30
  18. metadata +41 -161
  19. data/Rakefile +0 -97
  20. data/install.rb +0 -30
  21. data/lib/action_mailer/helpers.rb +0 -113
  22. data/lib/action_mailer/part.rb +0 -107
  23. data/lib/action_mailer/part_container.rb +0 -55
  24. data/lib/action_mailer/utils.rb +0 -7
  25. data/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb +0 -1466
  26. data/lib/action_mailer/vendor/text_format.rb +0 -10
  27. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/Makefile +0 -18
  28. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/address.rb +0 -392
  29. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/attachments.rb +0 -65
  30. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/base64.rb +0 -46
  31. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/compat.rb +0 -41
  32. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/config.rb +0 -67
  33. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/core_extensions.rb +0 -63
  34. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/encode.rb +0 -590
  35. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/header.rb +0 -962
  36. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/index.rb +0 -9
  37. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/interface.rb +0 -1162
  38. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/loader.rb +0 -3
  39. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/mail.rb +0 -578
  40. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/mailbox.rb +0 -496
  41. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/main.rb +0 -6
  42. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/mbox.rb +0 -3
  43. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/net.rb +0 -250
  44. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/obsolete.rb +0 -132
  45. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/parser.rb +0 -1060
  46. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/parser.y +0 -416
  47. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/port.rb +0 -379
  48. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/quoting.rb +0 -164
  49. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/require_arch.rb +0 -58
  50. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/scanner.rb +0 -49
  51. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/scanner_r.rb +0 -262
  52. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/stringio.rb +0 -280
  53. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/utils.rb +0 -362
  54. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/COPYING +0 -504
  55. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/README +0 -12
  56. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/big5freq.rb +0 -927
  57. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/big5prober.rb +0 -42
  58. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/chardistribution.rb +0 -238
  59. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/charsetgroupprober.rb +0 -112
  60. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/charsetprober.rb +0 -75
  61. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/codingstatemachine.rb +0 -64
  62. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/constants.rb +0 -42
  63. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/escprober.rb +0 -89
  64. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/escsm.rb +0 -244
  65. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/eucjpprober.rb +0 -88
  66. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/euckrfreq.rb +0 -596
  67. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/euckrprober.rb +0 -42
  68. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/euctwfreq.rb +0 -430
  69. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/euctwprober.rb +0 -42
  70. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/gb2312freq.rb +0 -474
  71. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/gb2312prober.rb +0 -42
  72. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/hebrewprober.rb +0 -289
  73. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/jisfreq.rb +0 -570
  74. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/jpcntx.rb +0 -229
  75. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/langbulgarianmodel.rb +0 -229
  76. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/langcyrillicmodel.rb +0 -330
  77. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/langgreekmodel.rb +0 -227
  78. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/langhebrewmodel.rb +0 -202
  79. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/langhungarianmodel.rb +0 -226
  80. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/langthaimodel.rb +0 -201
  81. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/latin1prober.rb +0 -147
  82. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/mbcharsetprober.rb +0 -89
  83. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/mbcsgroupprober.rb +0 -45
  84. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/mbcssm.rb +0 -542
  85. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/sbcharsetprober.rb +0 -124
  86. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/sbcsgroupprober.rb +0 -56
  87. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/sjisprober.rb +0 -88
  88. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb +0 -168
  89. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet/utf8prober.rb +0 -87
  90. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/vendor/rchardet-1.3/lib/rchardet.rb +0 -67
  91. data/lib/action_mailer/vendor/tmail-1.2.7/tmail/version.rb +0 -39
  92. data/lib/action_mailer/vendor/tmail-1.2.7/tmail.rb +0 -6
  93. data/lib/action_mailer/vendor/tmail.rb +0 -17
  94. data/lib/actionmailer.rb +0 -2
  95. data/test/abstract_unit.rb +0 -62
  96. data/test/asset_host_test.rb +0 -54
  97. data/test/delivery_method_test.rb +0 -51
  98. data/test/fixtures/asset_host_mailer/email_with_asset.html.erb +0 -1
  99. data/test/fixtures/auto_layout_mailer/hello.html.erb +0 -1
  100. data/test/fixtures/auto_layout_mailer/multipart.text.html.erb +0 -1
  101. data/test/fixtures/auto_layout_mailer/multipart.text.plain.erb +0 -1
  102. data/test/fixtures/explicit_layout_mailer/logout.html.erb +0 -1
  103. data/test/fixtures/explicit_layout_mailer/signup.html.erb +0 -1
  104. data/test/fixtures/first_mailer/share.erb +0 -1
  105. data/test/fixtures/helper_mailer/use_example_helper.erb +0 -1
  106. data/test/fixtures/helper_mailer/use_helper.erb +0 -1
  107. data/test/fixtures/helper_mailer/use_helper_method.erb +0 -1
  108. data/test/fixtures/helper_mailer/use_mail_helper.erb +0 -5
  109. data/test/fixtures/helpers/example_helper.rb +0 -5
  110. data/test/fixtures/layouts/auto_layout_mailer.html.erb +0 -1
  111. data/test/fixtures/layouts/auto_layout_mailer.text.erb +0 -1
  112. data/test/fixtures/layouts/spam.html.erb +0 -1
  113. data/test/fixtures/path.with.dots/funky_path_mailer/multipart_with_template_path_with_dots.erb +0 -1
  114. data/test/fixtures/raw_email +0 -14
  115. data/test/fixtures/raw_email10 +0 -20
  116. data/test/fixtures/raw_email12 +0 -32
  117. data/test/fixtures/raw_email13 +0 -29
  118. data/test/fixtures/raw_email2 +0 -114
  119. data/test/fixtures/raw_email3 +0 -70
  120. data/test/fixtures/raw_email4 +0 -59
  121. data/test/fixtures/raw_email5 +0 -19
  122. data/test/fixtures/raw_email6 +0 -20
  123. data/test/fixtures/raw_email7 +0 -66
  124. data/test/fixtures/raw_email8 +0 -47
  125. data/test/fixtures/raw_email9 +0 -28
  126. data/test/fixtures/raw_email_quoted_with_0d0a +0 -14
  127. data/test/fixtures/raw_email_with_invalid_characters_in_content_type +0 -104
  128. data/test/fixtures/raw_email_with_nested_attachment +0 -100
  129. data/test/fixtures/raw_email_with_partially_quoted_subject +0 -14
  130. data/test/fixtures/second_mailer/share.erb +0 -1
  131. data/test/fixtures/templates/signed_up.erb +0 -3
  132. data/test/fixtures/test_mailer/_subtemplate.text.plain.erb +0 -1
  133. data/test/fixtures/test_mailer/body_ivar.erb +0 -2
  134. data/test/fixtures/test_mailer/custom_templating_extension.text.html.haml +0 -6
  135. data/test/fixtures/test_mailer/custom_templating_extension.text.plain.haml +0 -6
  136. data/test/fixtures/test_mailer/implicitly_multipart_example.ignored.erb +0 -1
  137. data/test/fixtures/test_mailer/implicitly_multipart_example.rhtml.bak +0 -1
  138. data/test/fixtures/test_mailer/implicitly_multipart_example.text.html.erb +0 -10
  139. data/test/fixtures/test_mailer/implicitly_multipart_example.text.html.erb~ +0 -10
  140. data/test/fixtures/test_mailer/implicitly_multipart_example.text.plain.erb +0 -2
  141. data/test/fixtures/test_mailer/implicitly_multipart_example.text.yaml.erb +0 -1
  142. data/test/fixtures/test_mailer/included_subtemplate.text.plain.erb +0 -1
  143. data/test/fixtures/test_mailer/rxml_template.builder +0 -2
  144. data/test/fixtures/test_mailer/rxml_template.rxml +0 -2
  145. data/test/fixtures/test_mailer/signed_up.html.erb +0 -3
  146. data/test/fixtures/test_mailer/signed_up_with_url.erb +0 -5
  147. data/test/mail_helper_test.rb +0 -95
  148. data/test/mail_layout_test.rb +0 -123
  149. data/test/mail_render_test.rb +0 -116
  150. data/test/mail_service_test.rb +0 -1145
  151. data/test/quoting_test.rb +0 -105
  152. data/test/test_helper_test.rb +0 -129
  153. data/test/tmail_test.rb +0 -22
  154. data/test/url_test.rb +0 -76
data/CHANGELOG CHANGED
@@ -1,30 +1,27 @@
1
- *2.3.11 (February 9, 2011)*
2
- *2.3.10 (October 15, 2010)*
3
- *2.3.9 (September 4, 2010)*
4
- *2.3.8 (May 24, 2010)*
5
- *2.3.7 (May 24, 2010)*
1
+ *Rails 3.0 (pending)*
6
2
 
7
- * Version bump.
3
+ * Whole new API added with tests. See base.rb for full details. Old API is deprecated.
8
4
 
5
+ * The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted
9
6
 
10
- *2.3.6 (May 23, 2010)*
7
+ * Mail#content_type now returns the content_type field as a string. If you want the mime type of a mail, then you call Mail#mime_type (eg, text/plain), if you want the parameters of the content type field, you call Mail#content_type_parameters which gives you a hash, eg {'format' => 'flowed', 'charset' => 'utf-8'}
11
8
 
12
- * Upgrade TMail from 1.2.3 to 1.2.7. [Mikel Lindsaar]
9
+ * ActionMailer::Base :default_implicit_parts_order now is in the sequence of the order you want, no reversing of ordering takes place. The default order now is text/plain, then text/enriched, then text/html and then any other part that is not one of these three.
13
10
 
11
+ * Mail does not have "quoted_body", "quoted_subject" etc. All of these are accessed via body.encoded, subject.encoded etc
14
12
 
15
- *2.3.5 (November 25, 2009)*
13
+ * Every object in a Mail object returns an object, never a string. So Mail.body returns a Mail::Body class object, need to call #encoded or #decoded to get the string you want.
14
+ * Mail::Message#set_content_type does not exist, it is simply Mail::Message#content_type
16
15
 
17
- * Minor Bug Fixes and deprecation warnings
16
+ * Every mail message gets a unique message_id unless you specify one, had to change all the tests that check for equality with expected.encoded == actual.encoded to first replace their message_ids with control values
18
17
 
18
+ * Mail now has a proper concept of parts, remove the ActionMailer::Part and ActionMailer::PartContainer classes
19
19
 
20
- *2.3.4 (September 4, 2009)*
20
+ * Calling #encoded on any object returns it as a string ready to go into the output stream of an email, this means it includes the \r\n at the end of the lines and the object is pre-wrapped with \r\n\t if it is a header field. Also, the "encoded" value includes the field name if it is a header field.
21
21
 
22
- * Minor bug fixes.
22
+ * Attachments are only the actual attachment, with filename etc. A part contains an attachment. The part has the content_type etc. So attachments.last.content_type is invalid. But parts.last.content_type
23
23
 
24
-
25
- *2.3.3 (July 12, 2009)*
26
-
27
- * No changes, just a version bump.
24
+ * There is no idea of a "sub_head" in Mail. A part is just a Message with some extra functionality, so it just has a "header" like a normal mail message
28
25
 
29
26
 
30
27
  *2.3.2 [Final] (March 15, 2009)*
data/README CHANGED
@@ -5,51 +5,72 @@ are used to consolidate code for sending out forgotten passwords, welcome
5
5
  wishes on signup, invoices for billing, and any other use case that requires
6
6
  a written notification to either a person or another system.
7
7
 
8
+ Action Mailer is in essence a wrapper around Action Controller and the
9
+ Mail gem. It provides a way to make emails using templates in the same
10
+ way that Action Controller renders views using templates.
11
+
8
12
  Additionally, an Action Mailer class can be used to process incoming email,
9
13
  such as allowing a weblog to accept new posts from an email (which could even
10
14
  have been sent from a phone).
11
15
 
12
16
  == Sending emails
13
17
 
14
- The framework works by setting up all the email details, except the body,
15
- in methods on the service layer. Subject, recipients, sender, and timestamp
16
- are all set up this way. An example of such a method:
18
+ The framework works by initializing any instance variables you want to be
19
+ available in the email template, followed by a call to +mail+ to deliver
20
+ the email.
21
+
22
+ This can be as simple as:
17
23
 
18
- def signed_up(recipient)
19
- recipients recipient
20
- subject "[Signed up] Welcome #{recipient}"
21
- from "system@loudthinking.com"
22
- body :recipient => recipient
24
+ class Notifier < ActionMailer::Base
25
+ delivers_from 'system@loudthinking.com'
26
+
27
+ def welcome(recipient)
28
+ @recipient = recipient
29
+ mail(:to => recipient,
30
+ :subject => "[Signed up] Welcome #{recipient}")
31
+ end
23
32
  end
24
33
 
25
34
  The body of the email is created by using an Action View template (regular
26
- ERb) that has the content of the body hash parameter available as instance variables.
35
+ ERb) that has the instance variables that are declared in the mailer action.
36
+
27
37
  So the corresponding body template for the method above could look like this:
28
38
 
29
39
  Hello there,
30
40
 
31
41
  Mr. <%= @recipient %>
42
+
43
+ Thank you for signing up!
32
44
 
33
45
  And if the recipient was given as "david@loudthinking.com", the email
34
46
  generated would look like this:
35
47
 
36
- Date: Sun, 12 Dec 2004 00:00:00 +0100
48
+ Date: Mon, 25 Jan 2010 22:48:09 +1100
37
49
  From: system@loudthinking.com
38
50
  To: david@loudthinking.com
51
+ Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail>
39
52
  Subject: [Signed up] Welcome david@loudthinking.com
53
+ Mime-Version: 1.0
54
+ Content-Type: text/plain;
55
+ charset="US-ASCII";
56
+ Content-Transfer-Encoding: 7bit
40
57
 
41
58
  Hello there,
42
59
 
43
60
  Mr. david@loudthinking.com
44
61
 
45
- You never actually call the instance methods like signed_up directly. Instead,
46
- you call class methods like deliver_* and create_* that are automatically
47
- created for each instance method. So if the signed_up method sat on
48
- ApplicationMailer, it would look like this:
62
+ In previous version of rails you would call <tt>create_method_name</tt> and
63
+ <tt>deliver_method_name</tt>. Rails 3.0 has a much simpler interface, you
64
+ simply call the method and optionally call +deliver+ on the return value.
49
65
 
50
- ApplicationMailer.create_signed_up("david@loudthinking.com") # => tmail object for testing
51
- ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the email
52
- ApplicationMailer.new.signed_up("david@loudthinking.com") # won't work!
66
+ Calling the method returns a Mail Message object:
67
+
68
+ message = Notifier.welcome #=> Returns a Mail::Message object
69
+ message.deliver #=> delivers the email
70
+
71
+ Or you can just chain the methods together like:
72
+
73
+ Notifier.welcome.deliver # Creates the email and sends it immediately
53
74
 
54
75
  == Receiving emails
55
76
 
@@ -103,16 +124,13 @@ The Base class has the full list of configuration options. Here's an example:
103
124
  Action Mailer requires that the Action Pack is either available to be required immediately
104
125
  or is accessible as a GEM.
105
126
 
127
+ Additionally, Action Mailer requires the Mail gem, http://github.com/mikel/mail
106
128
 
107
129
  == Bundled software
108
130
 
109
- * tmail 0.10.8 by Minero Aoki released under LGPL
110
- Read more on http://i.loveruby.net/en/prog/tmail.html
111
-
112
131
  * Text::Format 0.63 by Austin Ziegler released under OpenSource
113
132
  Read more on http://www.halostatue.ca/ruby/Text__Format.html
114
133
 
115
-
116
134
  == Download
117
135
 
118
136
  The latest version of Action Mailer can be found at
@@ -1,29 +1,25 @@
1
1
  module ActionMailer
2
2
  module AdvAttrAccessor #:nodoc:
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- end
6
-
7
- module ClassMethods #:nodoc:
8
- def adv_attr_accessor(*names)
9
- names.each do |name|
10
- ivar = "@#{name}"
3
+ def adv_attr_accessor(*names)
4
+ names.each do |name|
5
+ ivar = "@#{name}"
11
6
 
12
- define_method("#{name}=") do |value|
13
- instance_variable_set(ivar, value)
7
+ class_eval <<-ACCESSORS, __FILE__, __LINE__ + 1
8
+ def #{name}=(value)
9
+ #{ivar} = value
14
10
  end
15
11
 
16
- define_method(name) do |*parameters|
17
- raise ArgumentError, "expected 0 or 1 parameters" unless parameters.length <= 1
18
- if parameters.empty?
19
- if instance_variable_names.include?(ivar)
20
- instance_variable_get(ivar)
21
- end
12
+ def #{name}(*args)
13
+ raise ArgumentError, "expected 0 or 1 parameters" unless args.length <= 1
14
+ if args.empty?
15
+ #{ivar} if instance_variable_names.include?(#{ivar.inspect})
22
16
  else
23
- instance_variable_set(ivar, parameters.first)
17
+ #{ivar} = args.first
24
18
  end
25
19
  end
26
- end
20
+ ACCESSORS
21
+
22
+ self.protected_instance_variables << ivar if self.respond_to?(:protected_instance_variables)
27
23
  end
28
24
  end
29
25
  end