Passing a Method as a Parameter in Ruby

Passing a method as a parameter in Ruby

You want a proc object:

gaussian = Proc.new do |dist, *args|
sigma = args.first || 10.0
...
end

def weightedknn(data, vec1, k = 5, weightf = gaussian)
...
weight = weightf.call(dist)
...
end

Just note that you can't set a default argument in a block declaration like that. So you need to use a splat and setup the default in the proc code itself.


Or, depending on your scope of all this, it may be easier to pass in a method name instead.

def weightedknn(data, vec1, k = 5, weightf = :gaussian)
...
weight = self.send(weightf)
...
end

In this case you are just calling a method that is defined on an object rather than passing in a complete chunk of code. Depending on how you structure this you may need replace self.send with object_that_has_the_these_math_methods.send


Last but not least, you can hang a block off the method.

def weightedknn(data, vec1, k = 5)
...
weight =
if block_given?
yield(dist)
else
gaussian.call(dist)
end
end
...
end

weightedknn(foo, bar) do |dist|
# square the dist
dist * dist
end

But it sounds like you would like more reusable chunks of code here.

Pass method name as parameter to another method

You want to use send:

def two(param, callback)
send(callback, param)
end

passing a method with parameters as an argument in ruby

echnically its not intended to give arguments to_json only takes getters. But you could do something along those lines:

class ObjectClassOfYourChoice
attr_accessor :current_user

def property_is_owned_by?(user = nil)
user ||= current_user
# rest of your code
end
end


@objects.each do |object|
object.current_user = current_user
end
render json: @objects.to_json(methods: [:property_is_owned_by?]

Although I wouldn't do it like this since you have to set for all the object and thats just codesmell.

ruby pass method as a parameter

You can use symbols to refer to methods:

def method_2(method_symbol, *args)
send method_symbol, *args
end

However, since you're calling the method on a specific object, you would either have to pass that in as an additional argument, or use a proc or a lambda, which is like a block wrapped in an object:

def method_2(proc, *args)
proc.call(*args)
end

method_2(->(param){ klass.foo(param) }, "test")

It's more common to just use blocks to do this:

def method_2(receiver, *args, &block)
yield receiver, *args
end

method_2(klass, "test") do |receiver, param|
receiver.foo(param)
end

All of these are fairly contrived examples; is there a specific problem you're trying to solve?

How to pass class method as parameter?

You have to use the right getter to receive the method object:

class A
def A.test(data)
puts data
end
end

def ps(fun)
fun.call(3)
end

ps(A.method(:test)) #=> 3

The method method returns the method-object, which can be executed with call.

How to pass operator as a parameter in ruby?

You can use public_send or (send depending the method):

operator = :>
5.public_send(operator, 4)
# true

public_send (as send) can receive a method as String or Symbol.

In case the method you're using isn't defined in the object class, Ruby will raise a NoMethodError.


You can also do receiver.method(method_name).call(argument), but that's just more typing:

5.method(operator).call(4)
# true

Thanks @tadman for the benchmark comparing send and method(...).call:

require 'benchmark'

Benchmark.bm do |bm|
repeat = 10000000

bm.report('send') { repeat.times { 5.send(:>, 2) } }
bm.report('method.call') { repeat.times { 5.method(:>).call(2) } }
end

# user system total real
# send 0.640115 0.000992 0.641107 ( 0.642627)
# method.call 2.629482 0.007149 2.636631 ( 2.644439)

How to pass by reference in Ruby?

Ruby is strictly pass-by-value, which means references in the caller's scope are immutable. Obviously they are mutable within the scope, since you can assign to them after all, but they don't mutate the caller's scope.

a = 'foo'

def bar(b)
b = 'bar'
end

bar(a)

a
# => 'foo'

Note, however, that the object can be mutated even if the reference cannot:

a = 'foo'

def bar(b)
b << 'bar' # the only change: mutate the object instead of the reference
b = 'baz'
end

bar(a)

a
# => 'foobar'

If the object you get passed is immutable, too, then there is nothing you can do. The only possibilities for mutation in Ruby are mutating the reference (by assignment) or asking an object to mutate itself (by calling methods on it).

You can return an updated value from your method and have the caller assign that to the reference:

a = :foo

def bar(b)
:"#{a}bar"
end

c = bar(a)

c
# => :foobar

Or you can wrap the immutable object in a mutable one and mutate that mutable wrapper:

a = [:foo]

def bar(b)
b[0] = :bar
end

bar(a)

a
# => [:bar]

[This is really the same thing as the second example above.]

But if you can't change anything, then you are stuck.

How to pass parameter in rails method?

def my_method?(params)`

will create an instance method, which thus must be called on an instance of your User class eg

User.new.my_method?(params) 

(as per the other comment)

If you want to be able to call it on your User class itself, then you must define it as a class method eg:

def self.my_method?(params)

How to pass a parameter to a method that is also a parameter itself in Ruby?

First you can not use 'end' as a variable name.

As for your question, I agree with Mladen Jablanovićyou that for this use case a block is better, but since you specifically asked about passing a method as a parameter to another method, you can use the 'send' method:

def track_time method, value
begin_time = Time.now
send method, value
end_time = Time.now
end_time - begin_time
end

def double(value)
value + value
end

p trcak_time(:double, 5)


Related Topics



Leave a reply



Submit