Sometimes, you don't need a gem for it.
This is a list of useful "snippets" for Ruby that are small but provide a lot of power. Copy them, modify them, and make them your own!
If you have a class where you are assigning all your arguments to variables, and you plan on adding more arguments over time, this will accomplish that in one line as opposed to having to hard-code your assignments. Default argument values will get assigned unless a different value has been passed.
method(__method__).parameters.each{|p| instance_variable_set("@#{p[1]}", binding.local_variable_get(p[1]))}
Example use:
class Model
def initialize guid: SecureRandom.uuid, name: 'untitled', metadata: {}, precedence: 0, created_at:Time.now, enabled: false
method(__method__).parameters.each{|p| instance_variable_set("@#{p[1]}", binding.local_variable_get(p[1]))}
end
end
One way to take this further would be to modify the snippet to also create attr_accessor
s!
You may stumble on a circumstance where you need to call a method that invokes the same method bound to another object. In my experience, this can happen when a method is called between objects that are bi-directionally related. This can cause infinite recursion(i.e. Stack Level Too Deep), which is baaaaaad. Sometimes, especially if you are building a deep hash structure, it may be okay if the deeper objects don't return anything from said method in order to prevent recursion.
def related_objects
return [] if stack_level_to_deep?(__method__)
# ... routine that returns objects that are related to the current one,
# whilst calling #related_objects on each of them, which would return this
# object and call this same method again!
end
private
def stack_level_too_deep? name
stack_level = caller.select{|s| s.include?("`related_objects'")}.count
stack_level > 2
end
The stack_level_too_deep?
method returns a boolean depending on if the specified method has been called more than twice. That way, you won't get related_objects
deeper than 2 levels. related_objects
uses that method to return an empty array if it returns true. This solution assumes that you aren't going to need related content on objects deeper than that number of levels.