how to refine this code mental block Rails - ruby-on-rails-3.1

I have these two methods that I would like to combine into one. But for the life of me I can't see how. NOOB big time. any help appreciated.
def is_active_no_category
'active' if params[:category].blank?
end
def is_active(category)
'active' if params[:category] == category.name.parameterize
end

With the below function passing a category as an argument is optional. If you do not pass an argument it will work like your is_active_no_category method. If you do pass an argument. It will work like your is_active method.
def is_active(category = nil)
'active' if (category.present? && params[:category] == category.name.parameterize) || (category.nil? && params[:category].blank?)
end
You may be able to make the if statement more compact, but you haven't stated the exact requirements for your function, so I gave you the most complete solution.

Related

Understanding Ruby code from Puppet module openstack/nova

I do not know Ruby very well and was hoping someone could help me understand some of what this bit of code is doing.
newproperty(:value, :array_matching => :all) do
desc 'The value of the setting to be defined.'
def insync?(is)
return true if #should.empty?
return false unless is.is_a? Array
return false unless is.length == #should.length
return (
is & #should == is or
is & #should.map(&:to_s) == is
)
end
I am not sure at all what this line ...
newproperty(:value, :array_matching => :all) do
... is doing. Is defining a function that accepts two parameters: value and array_matching? It is a loop? And I do not understand what the :array_matching => :all is all about.
Next is ...
desc 'The value of the setting to be defined.'
... Is this some sort of built in documentation? Next is this bit:
def insync?(is)
return true if #should.empty?
return false unless is.is_a? Array
return false unless is.length == #should.length
return (
is & #should == is or
is & #should.map(&:to_s) == is
)
I guess that a function called "insync" is being defined. Not sure what the '?' means. Also I guess #should is some global variable declared in the parent scope.
Thanks
I'll try to make assumptions and answer this as best I can from the info provided.
You probably have a function newproperty(x, y) <- accepts 2 arguments, somewhere in the associated model or helper. It's taking those inputs from some user interaction that assigns the :value and the :array_matching => :all is based on that :value.
desc is not a native Ruby function. It must be defined somewhere. For instance, this code would run:
def desc(x)
puts x
end
desc 'The value of the setting to be defined.'
It's a little unconventional but it would work.
The ? in def insync?(is) is part of the function name. Ruby is intended to be a very English-like language and since many functions evaluate to true or false, it's easier to read sometimes when you just make your function a question in itself.

Use calling method as parameter in ruby

Sorry if it isn't that expresive, but I really can't figure out how to title this question. The thing is like this:
I have to run this test:
Aspects.where has_parameters(3, 'optional')
I have this method:
def self.has_parameters(amount, status = 'everything')
if status == 'mandatory'
***.parameters.select do |param| param.first == :req end.size == amount
elsif status == 'optional'
***.parameters.select do |param| param.first == :opt end.size == amount
elsif status == 'everything'
***.parameters.size == amount
end
end
Aspects is the class that has both methods (where and has_parameters)
And a "where" method that lets pretend that returns a method (:symbol)
The problem is with replacing the *** with the method that "where" returns us.
So it would be like this:
Aspects.where will leave us, for example :singleton_method.. And I need to somehow make has_parameters to know that :singleton_method is the ***
Thank you!!! Any question just ask!!
Assuming that you want to build a fluent call chain (and I give up understanding the blocks do |param| ...) you can store the last value returned by where in a class field ##current_method
class Aspects
##current_method
def self.where(p)
##current_method = p.blah()
end
def self.has_parameters(amount, status = 'everything')
if status == 'mandatory'
##current_method.parameters {|p| ... }
end
end

Alternative ways to indicate a boolean value on a method

I am currently trying to refactor some duplicate code. There is one statement in particular which is giving me the most trouble:
some_class = double("some_class", some_method?: true)
I need to replace some_method with a variable name. However, the below won't work. Below is just an example of what I am trying to do.
some_method = unique_method
some_class = double("some_class", some_method?: true)
Does any know of alternative way to write:
some_method? # where some_method is a var.
I need to be able to call
some_class.some_method?
for my test case.
Any help is much appreciated. Thank you in advance.
Surround that with a string, it should be fine, alternatively you could use the :some_method? => value syntax.
def some_method?
puts "I am some_method? True"
end
some_hash_key = {:some_method? => true}
send(:some_method?)
my_variable = :some_method?
send(my_variable)
p some_hash_key
OK.. so at the end of the day, the above worked.. here is a working example of what I was trying to do.. I am using a lambda to simulate the function
some_method_one = lambda { return }
some_method_one = lambda { return }
picked_method = some_method_one
some_class = double("some_class", picked_one?: true )
some_class.picked_one? # this returns true
This code is completely over simplified. What I am intending to do (haven't finished writing the logic yet) is to create a shared_examples_for in rspec. I have 4 methods that will use the same logic for testing, so I need to pass in the method as a variable. Hopefully this makes sense, and helps someone out.. :-)

Ruby - Populate and Array with returned method values

So, pretend we have the following three methods that check a grid to determine if there is a winner, and will return true if there is.
def win_diagonal?
# Code here to check for diagonal win.
end
def win_horizontal?
# Code here to check for horizontal win.
end
def win_vertical?
# Code here to check for vertical win.
end
I would like to push the returned values of each method into an Array instead of literally using the method names. Is this possible?
def game_status
check_wins = [win_vertical?, win_diagonal?, win_horizontal?]
if check_wins.uniq.length != 1 # When we don't have only false returns from methods
return :game_over
end
end
What you are looking for will indeed work in ruby.
def hello_world?
"hello world!"
end
a = [hello_world?]
Prints out
=> ["hello world!"]
Hope that helps. IRB is your friend when you wonder if something is possible in Ruby :-)
Simpler way (and very readable) yet:
def game_status
win_vertical? || win_diagonal? || win_horizontal?
end
If, for example, win_vertical? returns true, the other algorithms won't even need to run. You return immediately.
Or, if you need to know in which way the user won, I mean, if you need to preserve the results of all methods after they ran, you can use a hash, like:
{:vertical => win_vertical?, :diagonal => win_diagonal?, :horizontal => win_horizontal?}
This solution, like the array one, is worse than the first one above for it runs all algorithms all the time. If they are complex, you may have a problem. =)
You can do something like this when you really want to store all return values in an array:
def game_status
check_wins = [win_vertical?, win_diagonal?, win_horizontal?]
return :game_over if check_wins.any?
end
For readability I would prefer:
def game_status
return :game_over if win_vertical? || win_diagonal? || win_horizontal?
end

Ruby metaprogramming, how does RSpec's 'should' work?

I was reading up on RSpec and I was trying to figure out how RSpec's "should" was implemented.
Could someone give a hand on how the meta nature of this function works?
The code is located here:
http://github.com/dchelimsky/rspec/blob/master/lib/spec/expectations/extensions/kernel.rb
TIA,
-daniel
Clarification:
target.should == 5
How did target's value get passed along to "should", which in turn was "=="'d against 5?
Take a look at class OperatorMatcher.
It all boils down to Ruby allowing you to leave out periods and parenthesis. What you are really writing is:
target.should.send(:==, 5)
That is, send the message should to the object target, then send the message == to whatever should returns.
The method should is monkey patched into Kernel, so it can be received by any object. The Matcher returned by should holds the actual which in this case is target.
The Matcher implements the method == which does the comparison with the expected which, in this case, is the number 5. A cut down example that you can try yourself:
module Kernel
def should
Matcher.new(self)
end
end
class Matcher
def initialize(actual)
#actual = actual
end
def == expected
if #actual == expected
puts "Hurrah!"
else
puts "Booo!"
end
end
end
target = 4
target.should == 5
=> Booo!
target = 5
target.should == 5
=> Hurrah!

Resources