This question already has answers here:
How to call methods dynamically based on their name? [duplicate]
(5 answers)
Closed 5 years ago.
I cant seem to follow this answer but maybe it's different from what I'm trying to achieve.
I have a string, that string can be different at time, I need to convert that string into a defined method name:
action = "get_name"
# The method
def get_name
puts "James"
end
# Calling the method
action # => undefined method `action' for main:Object
action can be any of my defined methods and the names are in a string format. Could I say action.to_method, you get what I mean ;)
I dont think I could say action.to_sym?
method(action).call
or
public_send(action)
Example:
method(action).call
#=> James
public_send(action)
#=> James
Be aware, though, that none of the above cares about the context, where was method originally defined, so both will call it in the context of the current object.
Related
This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 3 years ago.
I'm walking through the example project in the Rails 5 Test Prescriptions - Build a Healthy Codebase (published date: 2018) book and encountering this method:
#pages 29-30 of the book
class Project
.
.
def done?
tasks.all?(&:complete?) #only this line confused me, especially the `&` part
end
end
the syntax looks really strange to me since I just learned Ruby & Rails for more than one month..any hints just for pointing me to where I should read would be really appreciated
& is for passing block to method as a block (also used the other way in parameter list to make implicit block a parameter), it implicitly calls to_proc on passed object.
Symbol#to_proc for :symbol makes a proc{|param| param.symbol }
So your code is equvalent to tasks.all?{|task| task.complete? }
This question already has answers here:
What does the (unary) * operator do in this Ruby code?
(3 answers)
Closed 7 years ago.
I have a basic question about the mearning of * in a function call which I haven't been able to understand from online docs:
def self.new(*args, &block)
What does *args mean in the function call above?
consider a following method
def user(user_name)
puts user_name
end
so when you call
user("RPV")
Output:
RPV
=> nil
but what if you pass more then one argument like
user("RPV", "Marek")
it will give an error
wrong number of arguments (2 for 1)
To avoid this kind of error splat(*) operator is helpful
def user(*user_name)
puts user_name
end
and when you pass more than one argument it handles converts it in array
user("RPV", "Marek")
output:
RPV
Marek
nil
it makes user_name as an array
def user(user_name)
p user_name
end
user("RPV", "Marek")
output:
["RPV", "Marek"]
Hope you got the use of it.
It means you can pass any number of arguments that will be stored in args table inside of this method. Take a look: https://endofline.wordpress.com/2011/01/21/the-strange-ruby-splat/
This question already has answers here:
What do you call the -> operator in Ruby?
(3 answers)
Closed 8 years ago.
I was browsing Friendly_id gem code base and I found line with following assignment:
#defaults ||= ->(config) {config.use :reserved}
My questions are:
How do I interpret this line of code?
What does exactly -> do and what does it mean?
Is there any articles about it, how to use it?(Official Ruby documentation would be nice, I haven't found it)
Thank you for your help
This denotes the lambda. With this you are latching an anonymous function which takes a parameter config and computes a block using that variable.
The above expression can also be defined as:
#defaults ||= lambda {|config| config.use :reserved}
Proc is similar to lambda in Ruby, apart from few differences of return and break pattern. Proc can be called as a block saved as an object, while lambda is a method saved as an object. They find their roots in functional programming.
In short, a lambda is a named procedure, which can be saved as an object and can be called later.
inc = ->x{ x + 1 }
inc.call(3)
#=> 4
One common and interesting example of lambda is Rails Scope, where a method is simply assigned in name scope as lambda and can be later used as an action while ActiveRecord querying.
This question already has answers here:
Is there an inverse 'member?' method in ruby?
(5 answers)
Closed 8 years ago.
So a fairly common pattern I've run up against is something like this:
[:offer, :message].include? message.message_type
The inversion of wording there messes me up. So I wrote this little monkey patch for Symbol in specific.
def in? *scope
scope.include? self
end
So now I can do the previous this way:
message.message_type.in? :offer, :message
This works fine and I'm happy with it, but occasionally I need similar functionality for other objects. Model objects in Rails apps being the most common case but strings occasionally, etc.
What kind of issues would I run into if I monkey patched this directly into Object?
Rails (ActiveSupport) already patches Object with this method. Here is the documentation: http://api.rubyonrails.org/classes/Object.html#method-i-in-3F.
Returns true if this object is included in the argument. Argument must be any object which responds to #include?. Usage:
characters = ["Konata", "Kagami", "Tsukasa"]
"Konata".in?(characters) # => true
This will throw an ArgumentError if the argument doesn’t respond to #include?.
This question already has an answer here:
naked asterisk as parameter in method definition: def f(*)
(1 answer)
Closed 10 years ago.
When I was reading Rails code, I found this
def save(*)
create_or_update || raise(RecordNotSaved)
end
What does the * do? :O
I know what happens when we use it like *args, but in this case, it's just plain *.
ref https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb#L119
It means the same thing as it does when used with a parameter name: gobble up all the remaining arguments. Except, since there is no name to bind them to, the arguments are inaccessible. In other words: it takes any number of arguments but ignores them all.
Note that there actually is one way to use the arguments: when you call super without an argument list, the arguments get forwarded as-is to the superclass method.
In this specific case, save doesn't take any arguments. That's what happens with a naked splat. But, as you may be aware, calling save on an ActiveRecord model accepts options because this method gets overridden by ActiveRecord::Validations here:
https://github.com/rails/rails/blob/v3.1.3/activerecord/lib/active_record/validations.rb#L47
# The validation process on save can be skipped by passing <tt>:validate => false</tt>. The regular Base#save method is
# replaced with this when the validations module is mixed in, which it is by default.
def save(options={})
perform_validations(options) ? super : false
end