solnic / virtus

[DISCONTINUED ] Attributes on Steroids for Plain Old Ruby Objects
MIT License
3.77k stars 228 forks source link

Modify Defaults Lamba To Accept Variable Arguments #221

Closed jfelchner closed 10 years ago

jfelchner commented 10 years ago

I just hit a situation where I was using virtus on a class which had default values pulled from a configuration singleton. I got it to work just fine, but the syntax was rather verbose.

Would there be a way that the defaults lambda could take 0, 1 or 2 arguments depending on what the user needed access to?

For example here is my usage in the code I just wrote:

attribute :api_key, String,
                    :default => ->(request, attribute) { Ebay.config.api_key }

It'd be nice just to eliminate the variables:

attribute :api_key, String,
                    :default => -> { Ebay.config.api_key }

Thoughts?

dkubb commented 10 years ago

What about just using proc { Ebay.config.api_key } ?

jfelchner commented 10 years ago

Heh. That's what I get for just taking from the README without thinking. They DO both respond to call don't they? :wink:

@dkubb thank you.

jfelchner commented 10 years ago

For those who come after, using a Proc works because they don't verify the number of arguments passed to them.

dkubb commented 10 years ago

@jfelchner yeah, sorry I should've done more than just say what to do, I should've said why. My excuse is I was tired and taking a break in between coding sessions to knock out a few issues. ;)

dkubb commented 10 years ago

@jfelchner one more thing, even though I showed you a work-around I do agree with you that virtus should inspect the arity of the object it's about to call. If the arity is 0, then it should not bother passing in anything.

This would allow use to use normal method objects, eg:

require 'virtus'
require 'securerandom'

class User
  include Virtus.model

  attribute :name,  String
  attribute :token, String, default: SecureRandom.method(:hex)
end

In your specific example it could allow you to do this: (assuming api_key was an actual method and not something handled by #method_missing)

attribute :api_key, String, default: Ebay.config.method(:api_key)

... which I think would be quite elegant.

elskwid commented 10 years ago

I've opened issue #222 to track this idea. Thanks @dkubb and @jfelchner!

jfelchner commented 10 years ago

@dkubb agreed thanks!