Why can't the Mail block see my variable?
As Julik says, Mail#delivery
executes your block using #instance_exec
, which simply changes self
while running a block (you wouldn't be able to call methods #to
and #from
inside the block otherwise).
What you really can do here is to use a fact that blocks are closures. Which means that it "remembers" all the local variables around it.
recipient = params[:email]
Mail.deliver do
to recipient # 'recipient' is a local variable, not a method, not an instance variable
...
end
Again, briefly: - instance variables and method calls depend on
self
#instance_exec
changes theself
;- local variables don't depend on
self
and are remembered by blocks because blocks are closures.
Why i can't access my variable declared in package from sub declared in the same package in Perl?
You call Util::mysub()
several lines prior to assigning to the file scoped $var
.
If your package were in a seperate file, the use
statement and its implied BEGIN
block would give the assignment priority. Alternatively, you could put the package definition first or use your own BEGIN
block.
Why outside of block swift can't see value assigned to a uninitialized variable in the block?
Well, the message is not very helpful, and that's the problem. This pattern (which I call computed initialization) is perfectly legal and useful and — amazingly — you can even use let
instead of var
. But you must initialize the uninitialized variable by all possible paths before you use it. So you have:
var v:String
if true {
v = "Hello"
}
print(v) // error
But hold my beer and watch this:var v:String
if true {
v = "Hello"
} else {
v = "Goodbye"
}
print(v) // fine!
Or even:let v:String
if true {
v = "Hello"
} else {
v = "Goodbye"
}
print(v) // fine!
Amazing, eh?Now, you might say: OK, but true
will always be true so it's silly to make me fulfill the "all paths" rule. Too bad! The compiler insists anyway, and then lets you off later with a warning that the else
won't be executed. But a warning lets you compile; an error doesn't. The truth is that your example is very artificial. But this is a real-life possibility:
let v:String
if self.someBoolProperty {
v = "Hello"
} else {
v = "Goodbye"
}
print(v) // fine!
Not only is this sort of thing legal, it is actually the pattern that Apple recommends under certain slightly tricky circumstances. For instance, it is used in Apple's own example code showing how to use the Swift 5 Result struct:let result: Result<Int, EntropyError>
if count < AsyncRandomGenerator.entropyLimit {
// Produce numbers until reaching the entropy limit.
result = .success(Int.random(in: 1...100))
} else {
// Supply a failure reason when the caller hits the limit.
result = .failure(.entropyDepleted)
}
Undefined Variable Inside Mail::send in Laravel 5
The block of the closure (your function that sends the email) has not visibility of the outside block's scope.
So, if you want to access the variable from inside the closure, you have to explicitly pass it to the closure with the use keyword; like this:
Mail::send( 'emails.signed-notif',
['order_num' => $notif[0]->order_number],
function($m) use ($notif) /* here you're passing the variable */
{
$m->to('mis@qdf-phils.com', '')->subject('Customer Order'.$notif[0]->order_number.' is now signed');
} );
For more info on anonymous functions and closures check here What is the order of using blocks in Ruby
It's all about the context.
mail = Mail.new do
from 'mikel@test.lindsaar.net'
to 'you@test.lindsaar.net'
subject 'This is a test email'
body File.read('body.txt')
end
from
, to
methods (and the rest) are methods on Mail::Message
instance. For you to be able to call them in this nice DSL-manner, the block you pass to constructor is instance_eval'ed.What this means is that inside of this block, self
is no longer your mailer, but a mail message instead. As a result, your mailer method is not accessible.
Instead of instance_eval
, they could have just yield
or block.call
, but this wouldn't make the DSL possible.
As to why the local variable works: it's because ruby blocks are lexically-scoped closures (meaning, they retain local context of their declaration. If there was a local variable visible from where the block is defined, it'll remember the variable and its value when the block is called)
Alternative approach
Don't use the block form. Use this: https://github.com/mikel/mail/blob/0f9393bb3ef1344aa76d6dac28db3a4934c65087/lib/mail/message.rb#L92-L96mail = Mail.new
mail['from'] = 'mikel@test.lindsaar.net'
mail[:to] = 'you@test.lindsaar.net'
mail.subject 'This is a test email'
mail.body = 'This is a body'
Code
Try commenting/uncommenting some lines.class Mail
def initialize(&block)
# block.call(self) # breaks DSL
instance_eval(&block) # disconnects methods of mailer
end
def to(email)
puts "sending to #{email}"
end
end
class Mailer
def admin_mail
# get_recipient = 'vasya@example.com'
Mail.new do
to get_recipient
end
end
def get_recipient
'sergio@example.com'
end
end
Mailer.new.admin_mail
Twig (Symfony2) doesn't see variable in 'extend' block
This will work:
{% set layout = app.request.isXmlHttpRequest ? '::base-ajax.html.twig' : '::base.html.twig' %}
{% extends layout %}
Related Topics
How to Fix a Deadlock in Join() in Ruby
Monitor Multiple Rails Applications
How to Remove a Url's Trailing Slash in a Rails App? (In a Seo View)
How to Create Line Breaks in Ruby
What Is Ruby's Stringio Class Really
Alias_Method on Activerecord::Base Results in Nameerror
Creating a Ruby on Rails Environment on Windows, in a Vm Vagrant Box
Ruby Linkify for Urls in Strings
Difference Between @@ and @ in Ruby
Private Messages with Faye and Rails
Using a Self-Signed Certificate
Rails 3, Http Extensions (Webdav) and Rack App Mounting
Encoding Problems in Rails on Ruby 1.9.1
How to Show Longer Traces in Rails Testcases
Ruby Require 'File' Doesn't Work But Require './File' Does. Why