diff options
Diffstat (limited to 'actionmailer')
-rw-r--r-- | actionmailer/CHANGELOG | 5 | ||||
-rw-r--r-- | actionmailer/README.rdoc (renamed from actionmailer/README) | 46 | ||||
-rw-r--r-- | actionmailer/Rakefile | 18 | ||||
-rw-r--r-- | actionmailer/actionmailer.gemspec | 4 | ||||
-rw-r--r-- | actionmailer/install.rb | 30 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 38 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/deprecated_api.rb | 2 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/railtie.rb | 17 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/test_case.rb | 2 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/version.rb | 2 | ||||
-rw-r--r-- | actionmailer/test/base_test.rb | 168 | ||||
-rw-r--r-- | actionmailer/test/fixtures/asset_mailer/welcome.html.erb | 1 | ||||
-rw-r--r-- | actionmailer/test/mailers/asset_mailer.rb | 7 | ||||
-rw-r--r-- | actionmailer/test/mailers/base_mailer.rb | 114 | ||||
-rw-r--r-- | actionmailer/test/mailers/proc_mailer.rb | 16 |
15 files changed, 230 insertions, 240 deletions
diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG index f0b9368874..76eab935e5 100644 --- a/actionmailer/CHANGELOG +++ b/actionmailer/CHANGELOG @@ -1,3 +1,8 @@ +*Rails 3.0.0 [release candidate] (July 26th, 2010)* + +* No material changes + + *Rails 3.0.0 [beta 4] (June 8th, 2010)* * subject is automatically looked up on I18n using mailer_name and action_name as scope as in t(".subject") [JK] diff --git a/actionmailer/README b/actionmailer/README.rdoc index 2a4d507d8a..b52c993f56 100644 --- a/actionmailer/README +++ b/actionmailer/README.rdoc @@ -74,9 +74,9 @@ Or you can just chain the methods together like: == Receiving emails -To receive emails, you need to implement a public instance method called receive that takes a +To receive emails, you need to implement a public instance method called <tt>receive</tt> that takes a tmail object as its single parameter. The Action Mailer framework has a corresponding class method, -which is also called receive, that accepts a raw, unprocessed email as a string, which it then turns +which is also called <tt>receive</tt>, that accepts a raw, unprocessed email as a string, which it then turns into the tmail object and calls the receive instance method. Example: @@ -119,36 +119,16 @@ The Base class has the full list of configuration options. Here's an example: :authentication => :plain # :plain, :login or :cram_md5 } -== Dependencies -Action Mailer requires that the Action Pack is either available to be required immediately -or is accessible as a GEM. +== Download and installation -Additionally, Action Mailer requires the Mail gem, http://github.com/mikel/mail +The latest version of Action Mailer can be installed with Rubygems: -== Bundled software + % [sudo] gem install actionmailer -* Text::Format 0.63 by Austin Ziegler released under OpenSource - Read more on http://www.halostatue.ca/ruby/Text__Format.html +Source code can be downloaded as part of the Rails project on GitHub -== Download - -The latest version of Action Mailer can be found at - -* http://rubyforge.org/project/showfiles.php?group_id=361 - -Documentation can be found at - -* http://actionmailer.rubyonrails.org - - -== Installation - -You can install Action Mailer with the following command. - - % [sudo] ruby install.rb - -from its distribution directory. +* http://github.com/rails/rails/tree/master/actionmailer/ == License @@ -158,10 +138,10 @@ Action Mailer is released under the MIT license. == Support -The Action Mailer homepage is http://www.rubyonrails.org. You can find -the Action Mailer RubyForge page at http://rubyforge.org/projects/actionmailer. -And as Jim from Rake says: +API documentation is at + +* http://api.rubyonrails.com + +Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: - Feel free to submit commits or feature requests. If you send a patch, - remember to update the corresponding unit tests. If fact, I prefer - new feature to be submitted in the form of new unit tests. +* https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets diff --git a/actionmailer/Rakefile b/actionmailer/Rakefile index f20e7ea928..a47426bd07 100644 --- a/actionmailer/Rakefile +++ b/actionmailer/Rakefile @@ -1,8 +1,8 @@ -gem 'rdoc', '= 2.2' +gem 'rdoc', '>= 2.5.9' require 'rdoc' require 'rake' require 'rake/testtask' -require 'rake/rdoctask' +require 'rdoc/task' require 'rake/packagetask' require 'rake/gempackagetask' @@ -26,13 +26,13 @@ namespace :test do end # Generate the RDoc documentation -Rake::RDocTask.new { |rdoc| +RDoc::Task.new { |rdoc| rdoc.rdoc_dir = 'doc' rdoc.title = "Action Mailer -- Easy email delivery and testing" - rdoc.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object' rdoc.options << '--charset' << 'utf-8' - rdoc.template = ENV['template'] ? "#{ENV['template']}.rb" : '../doc/template/horo' - rdoc.rdoc_files.include('README', 'CHANGELOG') + rdoc.options << '-f' << 'horo' + rdoc.options << '--main' << 'README.rdoc' + rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG') rdoc.rdoc_files.include('lib/action_mailer.rb') rdoc.rdoc_files.include('lib/action_mailer/*.rb') rdoc.rdoc_files.include('lib/action_mailer/delivery_method/*.rb') @@ -50,9 +50,3 @@ task :release => :package do Rake::Gemcutter::Tasks.new(spec).define Rake::Task['gem:push'].invoke end - -desc "Publish the API documentation" -task :pdoc => [:rdoc] do - require 'rake/contrib/sshpublisher' - Rake::SshDirPublisher.new("rails@api.rubyonrails.org", "public_html/am", "doc").upload -end diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 2b7c21b3f2..daf30e434a 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -13,12 +13,12 @@ Gem::Specification.new do |s| s.homepage = 'http://www.rubyonrails.org' s.rubyforge_project = 'actionmailer' - s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] + s.files = Dir['CHANGELOG', 'README.rdoc', 'MIT-LICENSE', 'lib/**/*'] s.require_path = 'lib' s.requirements << 'none' s.has_rdoc = true s.add_dependency('actionpack', version) - s.add_dependency('mail', '~> 2.2.3') + s.add_dependency('mail', '~> 2.2.5') end diff --git a/actionmailer/install.rb b/actionmailer/install.rb deleted file mode 100644 index 8d7c140c3b..0000000000 --- a/actionmailer/install.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'rbconfig' -require 'find' -require 'ftools' - -include Config - -# this was adapted from rdoc's install.rb by way of Log4r - -$sitedir = CONFIG["sitelibdir"] -unless $sitedir - version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"] - $libdir = File.join(CONFIG["libdir"], "ruby", version) - $sitedir = $:.find {|x| x =~ /site_ruby/ } - if !$sitedir - $sitedir = File.join($libdir, "site_ruby") - elsif $sitedir !~ Regexp.quote(version) - $sitedir = File.join($sitedir, version) - end -end - -# the actual gruntwork -Dir.chdir("lib") - -Find.find("action_mailer", "action_mailer.rb") { |f| - if f[-3..-1] == ".rb" - File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true) - else - File::makedirs(File.join($sitedir, *f.split(/\//))) - end -} diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index ed4bea0c77..f742f982f2 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -41,16 +41,16 @@ module ActionMailer #:nodoc: # in the same manner as <tt>attachments[]=</tt> # # * <tt>headers[]=</tt> - Allows you to specify any header field in your email such - # as <tt>headers['X-No-Spam'] = 'True'</tt>. Note, while most fields (like <tt>To:</tt> + # as <tt>headers['X-No-Spam'] = 'True'</tt>. Note, while most fields like <tt>To:</tt> # <tt>From:</tt> can only appear once in an email header, other fields like <tt>X-Anything</tt> # can appear multiple times. If you want to change a field that can appear multiple times, - # you need to set it to nil first so that Mail knows you are replacing it, not adding - # another field of the same name.) + # you need to set it to nil first so that Mail knows you are replacing it and not adding + # another field of the same name. # # * <tt>headers(hash)</tt> - Allows you to specify multiple headers in your email such # as <tt>headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'})</tt> # - # * <tt>mail</tt> - Allows you to specify your email to send. + # * <tt>mail</tt> - Allows you to specify email to be sent. # # The hash passed to the mail method allows you to specify any header that a Mail::Message # will accept (any valid Email header including optional fields). @@ -66,7 +66,7 @@ module ActionMailer #:nodoc: # format.html # end # - # The block syntax is useful if also need to specify information specific to a part: + # The block syntax is also useful in providing information specific to a part: # # mail(:to => user.email) do |format| # format.text(:content_transfer_encoding => "base64") @@ -121,19 +121,18 @@ module ActionMailer #:nodoc: # # <%= users_url(:host => "example.com") %> # - # You will want to avoid using the <tt>name_of_route_path</tt> form of named routes because it doesn't + # You want to avoid using the <tt>name_of_route_path</tt> form of named routes because it doesn't # make sense to generate relative URLs in email messages. # # It is also possible to set a default host that will be used in all mailers by setting the <tt>:host</tt> - # option in the <tt>ActionMailer::Base.default_url_options</tt> hash as follows: - # - # ActionMailer::Base.default_url_options[:host] = "example.com" - # - # This can also be set as a configuration option in <tt>config/environment.rb</tt>: + # option as a configuration option in <tt>config/application.rb</tt>: # # config.action_mailer.default_url_options = { :host => "example.com" } # - # If you do decide to set a default <tt>:host</tt> for your mailers you will want to use the + # Setting <tt>ActionMailer::Base.default_url_options</tt> directly is now deprecated, use the configuration + # option mentioned above to set the default host. + # + # If you do decide to set a default <tt>:host</tt> for your mailers you want to use the # <tt>:only_path => false</tt> option when using <tt>url_for</tt>. This will ensure that absolute URLs are # generated because the <tt>url_for</tt> view helper will, by default, generate relative URLs when a # <tt>:host</tt> option isn't explicitly provided. @@ -155,7 +154,7 @@ module ActionMailer #:nodoc: # detect and use multipart templates, where each template is named after the name of the action, followed # by the content type. Each such detected template will be added as separate part to the message. # - # For example, if the following templates existed: + # For example, if the following templates exist: # * signup_notification.text.plain.erb # * signup_notification.text.html.erb # * signup_notification.text.xml.builder @@ -172,8 +171,7 @@ module ActionMailer #:nodoc: # # = Attachments # - # You can see above how to make a multipart HTML / Text email, to send attachments is just - # as easy: + # Sending attachment in emails is easy: # # class ApplicationMailer < ActionMailer::Base # def welcome(recipient) @@ -190,10 +188,8 @@ module ActionMailer #:nodoc: # # = Inline Attachments # - # You can also specify that a file should be displayed inline with other HTML. For example a - # corporate logo or a photo or the like. - # - # To do this is simple, in the Mailer: + # You can also specify that a file should be displayed inline with other HTML. This is useful + # if you want to display a corporate logo or a photo. # # class ApplicationMailer < ActionMailer::Base # def welcome(recipient) @@ -497,10 +493,10 @@ module ActionMailer #:nodoc: # You can also search for specific attachments: # # # By Filename - # mail.attachments['filename.jpg'] #=> Mail::Part object or nil + # mail.attachments['filename.jpg'] # => Mail::Part object or nil # # # or by index - # mail.attachments[0] #=> Mail::Part (first attachment) + # mail.attachments[0] # => Mail::Part (first attachment) # def attachments @_message.attachments diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 0070d8e016..7d57feba04 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/try' + module ActionMailer # This is the API which is deprecated and is going to be removed on Rails 3.1 release. # Part of the old API will be deprecated after 3.1, for a smoother deprecation process. diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb index d7b09b2dc6..ce6d8cc5b5 100644 --- a/actionmailer/lib/action_mailer/railtie.rb +++ b/actionmailer/lib/action_mailer/railtie.rb @@ -10,21 +10,16 @@ module ActionMailer end initializer "action_mailer.set_configs" do |app| - paths = app.config.paths - am = app.config.action_mailer + paths = app.config.paths + options = app.config.action_mailer - am.assets_dir ||= paths.public.to_a.first - am.javascripts_dir ||= paths.public.javascripts.to_a.first - am.stylesheets_dir ||= paths.public.stylesheets.to_a.first + options.assets_dir ||= paths.public.to_a.first + options.javascripts_dir ||= paths.public.javascripts.to_a.first + options.stylesheets_dir ||= paths.public.stylesheets.to_a.first ActiveSupport.on_load(:action_mailer) do - self.config.merge!(am) - include app.routes.url_helpers - - app.config.action_mailer.each do |k,v| - send "#{k}=", v - end + options.each { |k,v| send("#{k}=", v) } end end end diff --git a/actionmailer/lib/action_mailer/test_case.rb b/actionmailer/lib/action_mailer/test_case.rb index b91eed592a..f4d1bb59f1 100644 --- a/actionmailer/lib/action_mailer/test_case.rb +++ b/actionmailer/lib/action_mailer/test_case.rb @@ -28,7 +28,7 @@ module ActionMailer def determine_default_mailer(name) name.sub(/Test$/, '').constantize - rescue NameError => e + rescue NameError raise NonInferrableMailerError.new(name) end end diff --git a/actionmailer/lib/action_mailer/version.rb b/actionmailer/lib/action_mailer/version.rb index 8c19082f61..805c89be1d 100644 --- a/actionmailer/lib/action_mailer/version.rb +++ b/actionmailer/lib/action_mailer/version.rb @@ -3,7 +3,7 @@ module ActionMailer MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 5bc0491cff..fec0ecf477 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -2,139 +2,17 @@ require 'abstract_unit' require 'active_support/time' +require 'mailers/base_mailer' +require 'mailers/proc_mailer' +require 'mailers/asset_mailer' + class BaseTest < ActiveSupport::TestCase # TODO Add some tests for implicity layout render and url helpers # so we can get rid of old base tests altogether with old base. - class BaseMailer < ActionMailer::Base - self.mailer_name = "base_mailer" - - default :to => 'system@test.lindsaar.net', - :from => 'jose@test.plataformatec.com', - :reply_to => 'mikel@test.lindsaar.net' - - def welcome(hash = {}) - headers['X-SPAM'] = "Not SPAM" - mail({:subject => "The first email on new API!"}.merge!(hash)) - end - - def welcome_with_headers(hash = {}) - headers hash - mail - end - - def welcome_from_another_path(path) - mail(:template_name => "welcome", :template_path => path) - end - - def html_only(hash = {}) - mail(hash) - end - - def plain_text_only(hash = {}) - mail(hash) - end - - def inline_attachment - attachments.inline['logo.png'] = "\312\213\254\232" - mail - end - - def attachment_with_content(hash = {}) - attachments['invoice.pdf'] = 'This is test File content' - mail(hash) - end - - def attachment_with_hash - attachments['invoice.jpg'] = { :data => "\312\213\254\232)b", - :mime_type => "image/x-jpg", - :transfer_encoding => "base64" } - mail - end - - def attachment_with_hash_default_encoding - attachments['invoice.jpg'] = { :data => "\312\213\254\232)b", - :mime_type => "image/x-jpg" } - mail - end - - def implicit_multipart(hash = {}) - attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) - mail(hash) - end - - def implicit_with_locale(hash = {}) - mail(hash) - end - - def explicit_multipart(hash = {}) - attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) - mail(hash) do |format| - format.text { render :text => "TEXT Explicit Multipart" } - format.html { render :text => "HTML Explicit Multipart" } - end - end - - def explicit_multipart_templates(hash = {}) - mail(hash) do |format| - format.html - format.text - end - end - - def explicit_multipart_with_any(hash = {}) - mail(hash) do |format| - format.any(:text, :html){ render :text => "Format with any!" } - end - end - def explicit_multipart_with_options(include_html = false) - mail do |format| - format.text(:content_transfer_encoding => "base64"){ render "welcome" } - format.html{ render "welcome" } if include_html - end - end - - def explicit_multipart_with_one_template(hash = {}) - mail(hash) do |format| - format.html - format.text - end - end - - def implicit_different_template(template_name='') - mail(:template_name => template_name) - end - - def explicit_different_template(template_name='') - mail do |format| - format.text { render :template => "#{mailer_name}/#{template_name}" } - format.html { render :template => "#{mailer_name}/#{template_name}" } - end - end - - def different_layout(layout_name='') - mail do |format| - format.text { render :layout => layout_name } - format.html { render :layout => layout_name } - end - end - end - - class ProcMailer < ActionMailer::Base - default :to => 'system@test.lindsaar.net', - 'X-Proc-Method' => Proc.new { Time.now.to_i.to_s }, - :subject => Proc.new { give_a_greeting } - - def welcome - mail - end - - private - - def give_a_greeting - "Thanks for signing up this afternoon" - end - + def teardown + ActionMailer::Base.asset_host = nil + ActionMailer::Base.assets_dir = nil end test "method call to mail does not raise error" do @@ -570,6 +448,26 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Welcome from another path", mail.body.encoded) end + test "assets tags should use ActionMailer's asset_host settings" do + ActionMailer::Base.config.asset_host = "http://global.com" + ActionMailer::Base.config.assets_dir = "global/" + + mail = AssetMailer.welcome + + assert_equal(%{<img alt="Dummy" src="http://global.com/images/dummy.png" />}, mail.body.to_s.strip) + end + + test "assets tags should use a Mailer's asset_host settings when available" do + ActionMailer::Base.config.asset_host = "global.com" + ActionMailer::Base.config.assets_dir = "global/" + + AssetMailer.asset_host = "http://local.com" + + mail = AssetMailer.welcome + + assert_equal(%{<img alt="Dummy" src="http://local.com/images/dummy.png" />}, mail.body.to_s.strip) + end + # Before and After hooks class MyObserver @@ -609,6 +507,18 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Thanks for signing up this afternoon", mail.subject) end + test "action methods should be refreshed after defining new method" do + class FooMailer < ActionMailer::Base + # this triggers action_methods + self.respond_to?(:foo) + + def notify + end + end + + assert_equal ["notify"], FooMailer.action_methods + end + protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/fixtures/asset_mailer/welcome.html.erb b/actionmailer/test/fixtures/asset_mailer/welcome.html.erb new file mode 100644 index 0000000000..90d26130d9 --- /dev/null +++ b/actionmailer/test/fixtures/asset_mailer/welcome.html.erb @@ -0,0 +1 @@ +<%= image_tag "dummy.png" %>
\ No newline at end of file diff --git a/actionmailer/test/mailers/asset_mailer.rb b/actionmailer/test/mailers/asset_mailer.rb new file mode 100644 index 0000000000..f54a50d00d --- /dev/null +++ b/actionmailer/test/mailers/asset_mailer.rb @@ -0,0 +1,7 @@ +class AssetMailer < ActionMailer::Base + self.mailer_name = "asset_mailer" + + def welcome + mail + end +end diff --git a/actionmailer/test/mailers/base_mailer.rb b/actionmailer/test/mailers/base_mailer.rb new file mode 100644 index 0000000000..2c6de36ccf --- /dev/null +++ b/actionmailer/test/mailers/base_mailer.rb @@ -0,0 +1,114 @@ +class BaseMailer < ActionMailer::Base + self.mailer_name = "base_mailer" + + default :to => 'system@test.lindsaar.net', + :from => 'jose@test.plataformatec.com', + :reply_to => 'mikel@test.lindsaar.net' + + def welcome(hash = {}) + headers['X-SPAM'] = "Not SPAM" + mail({:subject => "The first email on new API!"}.merge!(hash)) + end + + def welcome_with_headers(hash = {}) + headers hash + mail + end + + def welcome_from_another_path(path) + mail(:template_name => "welcome", :template_path => path) + end + + def html_only(hash = {}) + mail(hash) + end + + def plain_text_only(hash = {}) + mail(hash) + end + + def inline_attachment + attachments.inline['logo.png'] = "\312\213\254\232" + mail + end + + def attachment_with_content(hash = {}) + attachments['invoice.pdf'] = 'This is test File content' + mail(hash) + end + + def attachment_with_hash + attachments['invoice.jpg'] = { :data => "\312\213\254\232)b", + :mime_type => "image/x-jpg", + :transfer_encoding => "base64" } + mail + end + + def attachment_with_hash_default_encoding + attachments['invoice.jpg'] = { :data => "\312\213\254\232)b", + :mime_type => "image/x-jpg" } + mail + end + + def implicit_multipart(hash = {}) + attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) + mail(hash) + end + + def implicit_with_locale(hash = {}) + mail(hash) + end + + def explicit_multipart(hash = {}) + attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) + mail(hash) do |format| + format.text { render :text => "TEXT Explicit Multipart" } + format.html { render :text => "HTML Explicit Multipart" } + end + end + + def explicit_multipart_templates(hash = {}) + mail(hash) do |format| + format.html + format.text + end + end + + def explicit_multipart_with_any(hash = {}) + mail(hash) do |format| + format.any(:text, :html){ render :text => "Format with any!" } + end + end + + def explicit_multipart_with_options(include_html = false) + mail do |format| + format.text(:content_transfer_encoding => "base64"){ render "welcome" } + format.html{ render "welcome" } if include_html + end + end + + def explicit_multipart_with_one_template(hash = {}) + mail(hash) do |format| + format.html + format.text + end + end + + def implicit_different_template(template_name='') + mail(:template_name => template_name) + end + + def explicit_different_template(template_name='') + mail do |format| + format.text { render :template => "#{mailer_name}/#{template_name}" } + format.html { render :template => "#{mailer_name}/#{template_name}" } + end + end + + def different_layout(layout_name='') + mail do |format| + format.text { render :layout => layout_name } + format.html { render :layout => layout_name } + end + end +end diff --git a/actionmailer/test/mailers/proc_mailer.rb b/actionmailer/test/mailers/proc_mailer.rb new file mode 100644 index 0000000000..6a79cd71fc --- /dev/null +++ b/actionmailer/test/mailers/proc_mailer.rb @@ -0,0 +1,16 @@ +class ProcMailer < ActionMailer::Base + default :to => 'system@test.lindsaar.net', + 'X-Proc-Method' => Proc.new { Time.now.to_i.to_s }, + :subject => Proc.new { give_a_greeting } + + def welcome + mail + end + + private + + def give_a_greeting + "Thanks for signing up this afternoon" + end + +end |