0

I have a method that's used in many places in my app, both in some controllers and other models.

class MyClass
  LONG_CONSTANT_1 = "function(x) { some_long_js_function }"
  LONG_CONSTANT_2 = "function(x) { another_really_long_js_function }"

  def self.my_group_method(my_constant)

    count = MyClass.collection.group(
      :keyf => my_constant,
      :reduce => "function(x, y) {y.count += x.count;}"
    )

  end  
end

So even though the method called inside my_group_method is related to MongoDB, the question is itself not related at all, basically I want to be able to call

MyClass.my_group_method(LONG_CONSTANT_2)

or

MyClass.my_group_method(LONG_CONSTANT_1)

(there are actually several more constants needed but the example has only 2)

Unfortunately my implementation here results in the error: NameError: wrong constant name LONG_CONSTANT_1

Any ideas at how to best implement this behavior? I'm likely going to have several long constants (which are actually JS functions as strings that get sent to MongoDB), what am I getting wrong about the design pattern I'm using here?

Any help would be greatly appreciated!

1 Answer 1

1

Sounds like you have a scoping problem with your constants. You want to call the class methods as:

MyClass.my_group_method(MyClass::LONG_CONSTANT_1)
MyClass.my_group_method(MyClass::LONG_CONSTANT_2)

I can get this NameError:

uninitialized constant Object::LONG_CONSTANT_1 (NameError)

from something structurally similar to your code but not a "wrong constant name" error.

If all that namespacing for the constants is too much then you could document the expected inputs (probably as symbols) and then inside your class:

INPUTS = (
    :long_symbol_1 => LONG_CONSTANT_1,
    :long_symbol_2 => LONG_CONSTANT_2
)

# Frobnicate the pancakes.
#
# The `which` argument should be `:long_symbol_1` or `:long_symbol_2`.
# etc.
def self.my_group_method(which)
    str = INPUTS[which]
    raise ArgumentError => "No idea what you're talking about" if(!str)
    #... continue on
end

That approach would give you some argument safety, your nice constants, and avoid the noise of having to prefix the argument with MyClass:: in the callers.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.