ruby lambda context
the code you are looking for is
temp.instance_eval(&callable)
Ruby assign context to lambda?
Yeah, but be careful with it, this one is really easy to abuse. I would personally be apprehensive of code like this.
class Rule
def get_rule
Proc.new { puts name }
end
end
class Person
attr_accessor :name
def init_rule
@name = "ruby"
instance_eval(&Rule.new.get_rule)
end
end
How do I change the context of lambda?
You're close. If you want the lambda(/block, really) to execute in the context of an instance of C
(since hi
is an instance method on C), then you'll need to instantiate it and then instance_exec the block on that new instance:
class C
def self.filter_clause param_1, &block
puts new.instance_exec &block
end
def hi
"hello"
end
end
class B
def self.filter(value, lambda)
code = lambda { filter_clause(value, &lambda) }
C.instance_exec(&code)
end
filter(:name, ->{ hi })
end
# => hello
Execute lambda in the context of another object
The issue here is that the receiver of instance_eval
is passed to the block as an argument. Procs allow for undeclared arguments, lambdas do not.
pr = proc {|*args| p args; a + 1 }
A.new.instance_eval &pr
[#<A:0x43668596>]
=> 6
If you declare your lambda such that it receives an argument, it works just fine:
> la = ->(recv) { a + 1 }
> A.new.instance_eval &la
=> 6
You could just (and probably want to) use instance_exec
instead though:
> la = -> { a + 1 }
> A.new.instance_exec &la
=> 6
> la = ->(add) { a + 1 + add }
> A.new.instance_exec 10, &la
=> 16
Calling a lambda from another lambda. Why does the order matter?
first = -> { defined? second }
second = -> { 'Ok' }
p first.call
results nil => The variable "second" is not defined in the lambda "first".
first = -> { binding.receiver }
second = -> { 'Ok' }
p first.call
results main => This means that it uses the current binding of main and thus the variable "second" is defined only in the binding.
first = -> { binding.local_variable_get(:second).call }
second = -> { 'Ok' }
p first.call
results "Ok". That's why the code also prints "Ok" when I ask for the content of the variable "second" of the binding.
Summary: The variable "second" is not defined in the lambda "first". The variable "second" is only defined in the binding. Therefore, the output of "local_variables" also returns "second" because the information is retrieved from the binding.
I also learned something myself. I hope I could help you!
when calling instance_eval(&lambda) to pass current context got error 'wrong number of arguments'
You are actually correct in your assumption. Self is being passed to the Proc
and to the lambda as it is being instance_eval
'ed. A major difference between Procs and lambdas is that lambdas check the arity of the block being being passed to them.
So:
class Rule
def get_rule
lambda { |s| puts s.inspect; puts name; }
end
end
class Person
attr_accessor :name
def init_rule
@name = "ruby"
instance_eval(&Rule.new.get_rule)
end
end
p = Person.new
p.init_rule
#<Person:0x007fd1099f53d0 @name="ruby">
ruby
Here I told the lambda to expect a block with arity 1 and as you see in the argument inspection, the argument is indeed the self
instance of Person class.
Getting the event body attributes in Ruby with AWS Lambda
event['body']
is going to return a string, a json string.
You need to parse it with something like this.
body = JSON.parse(event['body'])
my_int = body['message']
Also if you were to do.
puts event.inspect
instead of
puts "#{event['body']}"
you would have been able to see that body returned a string and not an object. I hope that helps and good luck.
Ruby lambda's proc's and 'instance_eval'
From the docs
For procs created using lambda or ->() an error is generated if the
wrong number of parameters are passed to a Proc with multiple
parameters. For procs created using Proc.new or Kernel.proc, extra
parameters are silently discarded.
In your case both lamb
and proc
called with one parameter
From the docs of instance_eval
When instance_eval is given a block, obj is also passed in as the
block's only argument
instance_eval
is method of BasicObject
class and can be called within instance. So given block will have access for private methods for example.
class Test
def call
secret_number + 100
end
private
def secret_number
42
end
end
test = Test.new
show_secret = -> (obj) { puts secret_number }
test.instance_eval(&show_secret) # print 42
Without instance self
of current context will be passed as an argument. I think instance_eval
was designed more for calling it within objects.
From the docs of instance_eval
In order to set the context, the variable self is set to obj while the
code is executing, giving the code access to obj's instance variables
and private methods.
Related Topics
Heroku App Fails to Start - 'Require': No Such File to Load -- Sinatratestapp (Loaderror)
Rails 3: Call Functions Inside Controllers
Do Ruby 1.8 and 1.9 Have the Same Hash Code for a String
Ruby: Write Escaped String to Yaml
Star Rating in Ajax with Ruby on Rails
Why Is Devise Not Displaying Authentication Errors on Sign in Page
Aptana 3 Ruby Debugger - Exception in Debugthread Loop: Undefined Method 'Is_Binary_Data'
How to Add Child Nodes in Nodeset Using Nokogiri
How Does MACports Install Packages? How to Activate a Ruby Installation Done via MACports
Using Soap and Other Standard Libraries in Ruby 1.9.2
Can a Ruby Script Tell What Directory It's In
How to Add Confirm Message with Link_To Ruby on Rails
How to Output Names of Ruby Unit Tests
Sinatra - Response.Set_Cookie Doesn't Work
Check If String Contains Any Substring in an Array in Ruby
How to Organize Minitest/Unit Tests
Define_Method: How to Dynamically Create Methods with Arguments