Skip to content

Instantly share code, notes, and snippets.

@TheDauthi
Created May 28, 2016 18:41
Show Gist options
  • Save TheDauthi/b5500d8f00e86d1285bf63ad96cf3c35 to your computer and use it in GitHub Desktop.
Save TheDauthi/b5500d8f00e86d1285bf63ad96cf3c35 to your computer and use it in GitHub Desktop.
# Allows repeated partial application without automatic dispatch
class PartiallyAppliedMethod < Proc
def apply(*curried_args)
(@curried_args ||= []).push(*curried_args)
self
end
def call(*params)
super(*@curried_args, *params)
end
end
@TheDauthi
Copy link
Author

Usage Examples:

    def curry_method(method, *args)
      PartiallyAppliedMethod.new(&self.method(method)).apply(*args)
    end

@TheDauthi
Copy link
Author

Using this to dynamically create lazy variables:

# This looks a lot more complex than it is.
# But Moose has it built in.
def add_attribute(statistic, value)
  # Create a writer first.
  singleton_class.send(:attr_writer, statistic.to_sym)
  # The storage name is always @statistic.
  statistic_variable_name = "@#{statistic}"
  # Set the initial value.  This is either a proc or a real value.
  # Since we JUST DEFINED the thing, I feel okay with using instance_variable_set
  instance_variable_set(statistic_variable_name, value)
  # Define the read accessor
  singleton_class.send(:define_method, statistic) do
    # Get the last thing we stored.
    result = instance_variable_get(statistic_variable_name)
    # If it was a Proc, call it...
    if result.is_a?(Proc)
      result = result.call
      # And store the result for the next time.
      instance_variable_set(statistic_variable_name, result)
    end
    # And return the (possibly just now retrieved) result
    result
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment