<commit_before>== BasicAssumption

A clone of DecentExposure with a psuedo-modular interface for providing
custom defaults. It provides a declarative interface for specifying helper
methods that is useful in Rails applications.

=== What is DecentExposure?

It's a plugin written by {<NAME>}[http://voxdolo.me/] that provides a way of
cleaning up Rails controller and view code. Find it at
{its GitHub repository}[http://github.com/voxdolo/decent_exposure].

It represents an idiom for writing certain kinds of code in a declarative way.
Particularly in your Rails apps, it's worth checking out. BasicAssumption is
another implementation of the idiom. It exists largely because I felt like
practicing writing a gem, though it does have a differentiating feature or two.
Check the BasicAssumption::Configuration options for enabling compatibility
with the DecentExposure API.

== Install BasicAssumption

It's a gem, so do the usual:

    [sudo] gem install basic_assumption

=== Using it in a Rails app

For Rails 2, in environment.rb:

    gem.config 'basic_assumption'

For Rails 3, in your Gemfile:

    gem 'basic_assumption', :require => ['basic_assumption', 'basic_assumption/rails']

It's possible to use BasicAssumption in your Rails 3 app without requiring
'basic_assumption/rails', and will in fact allow more flexibility if you don't,
but will incur the cost of additional setup. See the file
'lib/basic_assumption/rails.rb' for guidance.

To use the library in another context, it is enough to extend the
BasicAssumption module inside the class you would like it available.

== Examples

=== Inside a Rails controller

The presumed most-common use case for BasicAssumption is in a Rails app. By
default, BasicAssumption is extended within ActionController::Base, making it
available inside your controllers.

The most important (of the few) methods made available in controller classes is
+assume+, which is used to declaratively define a resource of some kind in
controller instances and to make that resource available inside corresponding
views. For all the wordiness of the description, it's a simple concept, as
illustrated below. First, we will use +assume+ to expose a resource inside our
controller actions that will take the value resulting from the block passed to
+assume+. In this case, the resource will be called 'widget':

    class WidgetController < ActionController::Base

      assume(:widget) { Widget.find(params[:id]) }

      ...

      def purchase
        current_user.purchase!(widget)
        render :template => 'widgets/purchase_complete'
      end
    end

And then inside of the 'widgets/purchase_complete.html.haml' view:

    %h2= "#{current_user.name}, your purchase is complete!
    .widget
      %span#thanks
        = "Thank you for purchasing #{widget.name}!"
      %table#details
        %tr
          %td Cost
          %td= widget.cost
        %tr
          %td Manufacturer
          %td= widget.manufacturer

By calling +assume+ with the symbol :widget and passing it a block, an instance
method is created on the controller class that is also exposed as a helper
inside views. For more details on how BasicAssumption is wired into your Rails
app, please see the BasicAssumption::Railtie documentation.

=== When to use it

Whenever you find yourself writing a +before_filter+ in a Rails controller
that sets instance variables as part of the context of your request, you should
probably use an assumption instead. Because BasicAssumption is written to use
lazy evaluation, there's no need to worry about avoiding calls on actions that
don't need some particular setup.

For example, this:

    class RecordController < ActionController::Base
      before_filter :find_record, :only => [:show, :edit, :update, :destroy]

      ...

      protected
      def find_record
        @record = Record.find(params[:record_id] || params[:id])
      end
    end

would become this:

    class RecordController < ActionController::Base
      assume :record
    end

and would have the added benefit of not tossing instance variables around.
If a controller has protected or hidden methods that find or create instance
variables used in actions and/or views, it might be cleaner to use an
assumption instead.

BasicAssumption allows for a simple, declarative, and very lightweight approach
to RESTful controllers.  It also can make for a cleaner, more testable interface
for controller or view testing. There may even be uses outside of Rails apps.
Give it a shot.

=== Defaults

BasicAssumption allows for default behavior to be associated with methods
created by +assume+ whenever a block is not passed. Here is a simple example:

    class WidgetController < ActionController::Base
      default_assumption { Widget.find(params[:id]) }
      assume(:widget)

      ...
    end

This will provide the same behavior as the similar example above. It is also
possible to pass a proc or lambda directly.

Finally, a symbol may be passed if it corresponds to a
specifically-defined helper class that came packaged with the library or was
provided by the application.

=== In Rails

In Rails, a useful default is already active out of the box. It attempts to
guess the name of a class derived from ActiveRecord::Base and do a find on it
based on an id available in the +params+ of the request. Because of this, the
following two constructs would be equivalent in your controllers:

    assume(:film) { Film.find(params[:film_id] || params[:id]) }
    # The above line is exactly the same as:
    assume(:film)

Please see +SimpleRails+ for details of implementation. Because finding on :id
could be considered dangerous, there is another default available for use,
+CautiousRails+, that will only find on :name_id. (In the example above,
this would be :film_id.) Enable that for one of your controllers like so:

    class FilmController < ActionController::Base
      default_assumption :cautious_rails
    end

Default assumptions are inherited by derived classes.

=== Supplying custom default behavior classes

There is an ability to provide custom, modular default extensions to
BasicAssumption and then use them by passing a symbol, as in the following:

    class WidgetController < ActionController::Base
      default_assumption :my_custom_default_class
    end

The symbol is converted to a class in the same manner as Rails classify/
constantize operates, but it is looked up in the
BasicAssumption::DefaultAssumption namespace. Please see the documentation for
+DefaultAssumption+ for a discussion and +SimpleRails+ for an example of this.

=== Configuration

There are a couple of simple configuration settings that can be set inside of
a configuration block that can be used in places such as Rails initializer
blocks. For more information, see BasicAssumption::Configuration.

== Issues

=== Memoization

Methods that are created by BasicAssumption#assume memoize the result of the
block the invoke when they're called. Because of that, the block is only
evaluated once during the lifespan of each object of the class that used
+assume+. This means that a method created by assuming can be used multiple
times inside of a Rails controller object and associated view(s) without
invoking the associated block multiple times, but it also means that any
behavior of the block that is meant to vary over multiple invocations will not
be observed.

=== Exceptions

Using BasicAssumption may change the exception handling strategy inside your
classes. In Rails, the +rescue_from+ method may be useful.

=== Other

There are probably others, and when I remember what they were, I'll write them
up.

== Hacking/running specs

There is nothing special about running the specs, aside from ensuring the
RUBYOPT environment variable is set to your preferred Ruby dependency
manager. For example, if RubyGems:

    export RUBYOPT=rubygems

If you're unfamiliar with why this is being done, take a look
{here for a start}[http://tomayko.com/writings/require-rubygems-antipattern].
Other than that, please feel free to fork and send back pull requests! Thanks.

== But should I use it?

Sure! Absolutely. I think it's a cool idea that lets you cut down on line
noise, particularly in your Rails controllers. You may want to consider going
with {DecentExposure}[http://github.com/voxdolo/decent_exposure], simply
because it's used by much of {Hashrocket}[http://www.hashrocket.com/]
and BasicAssumption is used, so far as I know, only by me. But so far as I know
BasicAssumption is pretty solid, and I'm happy to accept bug fixes and field
feature requests. If you use it, feel free to let me know! Email mby [at]
mattyoho [dot] com with questions, comments, or non-sequiters.
<commit_msg>Add note on restful_rails to README<commit_after>== BasicAssumption

A clone of DecentExposure with a psuedo-modular interface for providing
custom defaults. It provides a declarative interface for specifying helper
methods that is useful in Rails applications.

=== What is DecentExposure?

It's a plugin written by {<NAME>}[http://voxdolo.me/] that provides a way of
cleaning up Rails controller and view code. Find it at
{its GitHub repository}[http://github.com/voxdolo/decent_exposure].

It represents an idiom for writing certain kinds of code in a declarative way.
Particularly in your Rails apps, it's worth checking out. BasicAssumption is
another implementation of the idiom. It exists largely because I felt like
practicing writing a gem, though it does have a differentiating feature or two.
Check the BasicAssumption::Configuration options for enabling compatibility
with the DecentExposure API.

== Install BasicAssumption

It's a gem, so do the usual:

    [sudo] gem install basic_assumption

=== Using it in a Rails app

For Rails 2, in environment.rb:

    gem.config 'basic_assumption'

For Rails 3, in your Gemfile:

    gem 'basic_assumption', :require => ['basic_assumption', 'basic_assumption/rails']

It's possible to use BasicAssumption in your Rails 3 app without requiring
'basic_assumption/rails', and will in fact allow more flexibility if you don't,
but will incur the cost of additional setup. See the file
'lib/basic_assumption/rails.rb' for guidance.

To use the library in another context, it is enough to extend the
BasicAssumption module inside the class you would like it available.

== Examples

=== Inside a Rails controller

The presumed most-common use case for BasicAssumption is in a Rails app. By
default, BasicAssumption is extended within ActionController::Base, making it
available inside your controllers.

The most important (of the few) methods made available in controller classes is
+assume+, which is used to declaratively define a resource of some kind in
controller instances and to make that resource available inside corresponding
views. For all the wordiness of the description, it's a simple concept, as
illustrated below. First, we will use +assume+ to expose a resource inside our
controller actions that will take the value resulting from the block passed to
+assume+. In this case, the resource will be called 'widget':

    class WidgetController < ActionController::Base

      assume(:widget) { Widget.find(params[:id]) }

      ...

      def purchase
        current_user.purchase!(widget)
        render :template => 'widgets/purchase_complete'
      end
    end

And then inside of the 'widgets/purchase_complete.html.haml' view:

    %h2= "#{current_user.name}, your purchase is complete!
    .widget
      %span#thanks
        = "Thank you for purchasing #{widget.name}!"
      %table#details
        %tr
          %td Cost
          %td= widget.cost
        %tr
          %td Manufacturer
          %td= widget.manufacturer

By calling +assume+ with the symbol :widget and passing it a block, an instance
method is created on the controller class that is also exposed as a helper
inside views. For more details on how BasicAssumption is wired into your Rails
app, please see the BasicAssumption::Railtie documentation.

=== When to use it

Whenever you find yourself writing a +before_filter+ in a Rails controller
that sets instance variables as part of the context of your request, you should
probably use an assumption instead. Because BasicAssumption is written to use
lazy evaluation, there's no need to worry about avoiding calls on actions that
don't need some particular setup.

For example, this:

    class RecordController < ActionController::Base
      before_filter :find_record, :only => [:show, :edit, :update, :destroy]

      ...

      protected
      def find_record
        @record = Record.find(params[:record_id] || params[:id])
      end
    end

would become this:

    class RecordController < ActionController::Base
      assume :record
    end

and would have the added benefit of not tossing instance variables around.
If a controller has protected or hidden methods that find or create instance
variables used in actions and/or views, it might be cleaner to use an
assumption instead.

BasicAssumption allows for a simple, declarative, and very lightweight approach
to RESTful controllers.  It also can make for a cleaner, more testable interface
for controller or view testing. There may even be uses outside of Rails apps.
Give it a shot.

=== Defaults

BasicAssumption allows for default behavior to be associated with methods
created by +assume+ whenever a block is not passed. Here is a simple example:

    class WidgetController < ActionController::Base
      default_assumption { Widget.find(params[:id]) }
      assume(:widget)

      ...
    end

This will provide the same behavior as the similar example above. It is also
possible to pass a proc or lambda directly.

Finally, a symbol may be passed if it corresponds to a
specifically-defined helper class that came packaged with the library or was
provided by the application.

=== In Rails

In Rails, a useful default is already active out of the box. It attempts to
guess the name of a class derived from ActiveRecord::Base and do a find on it
based on an id available in the +params+ of the request. Because of this, the
following two constructs would be equivalent in your controllers:

    assume(:film) { Film.find(params[:film_id] || params[:id]) }
    # The above line is exactly the same as:
    assume(:film)

Please see +SimpleRails+ for details of implementation. Because finding on :id
could be considered dangerous, there is another default available for use,
+CautiousRails+, that will only find on :name_id. (In the example above,
this would be :film_id.) Enable that for one of your controllers like so:

    class FilmController < ActionController::Base
      default_assumption :cautious_rails
    end

Another option is :restful_rails, which attempts to provide appropriate
behavior for the basic RESTful actions. Please see +RestfulRails+ for a
description of how it works.

Default assumptions are inherited by derived classes.

=== Supplying custom default behavior classes

There is an ability to provide custom, modular default extensions to
BasicAssumption and then use them by passing a symbol, as in the following:

    class WidgetController < ActionController::Base
      default_assumption :my_custom_default_class
    end

The symbol is converted to a class in the same manner as Rails classify/
constantize operates, but it is looked up in the
BasicAssumption::DefaultAssumption namespace. Please see the documentation for
+DefaultAssumption+ for a discussion and +SimpleRails+ for an example of this.

=== Configuration

There are a couple of simple configuration settings that can be set inside of
a configuration block that can be used in places such as Rails initializer
blocks. For more information, see BasicAssumption::Configuration.

== Issues

=== Memoization

Methods that are created by BasicAssumption#assume memoize the result of the
block the invoke when they're called. Because of that, the block is only
evaluated once during the lifespan of each object of the class that used
+assume+. This means that a method created by assuming can be used multiple
times inside of a Rails controller object and associated view(s) without
invoking the associated block multiple times, but it also means that any
behavior of the block that is meant to vary over multiple invocations will not
be observed.

=== Exceptions

Using BasicAssumption may change the exception handling strategy inside your
classes. In Rails, the +rescue_from+ method may be useful.

=== Other

There are probably others, and when I remember what they were, I'll write them
up.

== Hacking/running specs

There is nothing special about running the specs, aside from ensuring the
RUBYOPT environment variable is set to your preferred Ruby dependency
manager. For example, if RubyGems:

    export RUBYOPT=rubygems

If you're unfamiliar with why this is being done, take a look
{here for a start}[http://tomayko.com/writings/require-rubygems-antipattern].
Other than that, please feel free to fork and send back pull requests! Thanks.

== But should I use it?

Sure! Absolutely. I think it's a cool idea that lets you cut down on line
noise, particularly in your Rails controllers. You may want to consider going
with {DecentExposure}[http://github.com/voxdolo/decent_exposure], simply
because it's used by much of {Hashrocket}[http://www.hashrocket.com/]
and BasicAssumption is used, so far as I know, only by me. But so far as I know
BasicAssumption is pretty solid, and I'm happy to accept bug fixes and field
feature requests. If you use it, feel free to let me know! Email mby [at]
mattyoho [dot] com with questions, comments, or non-sequiters.

{'fraction_non_alphanumeric': 0.054390934844192634, 'fraction_numerical': 0.00045325779036827196, 'mean_word_length': 4.17624633431085, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6556058', 'n_tokens_mistral': 4673, 'n_tokens_neox': 4377, 'n_words': 2410}