Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6733 (new enhancement)

Opened 3 years ago

Last modified 2 years ago

[PATCH] DRY evaluation of proc/string/symbol/class arguments

Reported by: obrie Assigned to: David
Priority: normal Milestone: 2.x
Component: ActiveSupport Version: edge
Severity: normal Keywords: dry evaluate call block tested needy
Cc:

Description

I've seen this both in several plugins and multiple places within ActiveRecord where an argument needs to be evaluated like so:

With Object obj, Method m, and Arguments a

  1. If m is a symbol, then call m on obj with the arguments a
  2. If m is a string, then evaluate m with a binding to obj
  3. If m is an object that responds to call (like Proc and Method), then call m.call with obj as the first argument + any additional arguments a

I feel this should by DRYed and available to all Objects. I, myself, am using it to duplicate functionality similar to how :if works on validations. I'd like to be able to use all of these different configurations without duplicating code and having to maintain it along with everything else. In addition, you get to DRY up some of the code in ActiveRecord's validations.

I'm proposing adding a new method to all Objects, eval_call, which will take 2 parameters: a symbol/string/Proc/Method/etc. and additional arguments (just like send).

So you would have something like the following (as shown in the comments and tests of the patch):

class SwitchChanger
  def self.call(switch)
    switch.state = "on"
  end
end

class Switch
  attr_accessor :state
  
  def initialize
    state = "on"
  end
  
  def change_state(value)
    state = value
    true
  end
end

s = Switch.new
s.eval_call("@state")                         # => "on"
s.eval_call(Proc.new {|switch| switch.state}) # => "on"
s.eval_call(:change_state, "off")             # => true
s.state                                       # => "off"
s.eval_call(SwitchChanger)                    # => "on"
s.state                                       # => "on"

Attachments

eval_call.diff (9.2 kB) - added by obrie on 11/29/06 21:44:13.
Initial attempt.

Change History

11/29/06 21:44:13 changed by obrie

  • attachment eval_call.diff added.

Initial attempt.

11/29/06 21:44:49 changed by obrie

  • keywords changed from dry evaluate call block to dry evaluate call block tested.
  • version set to edge.
  • type changed from defect to enhancement.

02/24/07 17:45:21 changed by josh

  • keywords changed from dry evaluate call block tested to dry evaluate call block tested needy.
  • milestone changed from 1.2 to 1.x.