Ruby string interpolation not working when called from an included file - ruby

I have two files: urls.rb and testcase.rb. urls.rb has the following:
$event = "/sendmessage/#{id}"
The id in the url is generated in testcase.rb. This is the code in testcase.rb:
require 'urls.rb'
id = 100
puts $event
I am seeing the following error:
undefined local variable or method `id' for main:Object (NameError)
How do I resolve this error?

Local variables like id cannot be called across files. Their scopes are limited within a file. In order to use it, you have to assign id in the same file as it is used. Furthermore, your assignment of id after requiring 'urls.rb' is meaningless.

The problem is that you are attempting to use id in urls.rb before it has been defined by testcase.rb. Your code is functionally equivalent to the following:
$event = "/sendmessage/#{id}"
id = 100
puts $event
This does not work because you are attempting to call id before it has been defined. You must define the variable first:
id = 100
$event = "/sendmessage/#{id}"
puts $event
Here it works because you have defined id before you're trying to call it.
When troubleshooting a problem like this, consider how it would have to work if you were not separating it into different files.
So without knowing more about what you're trying to accomplish, just make sure you have defined a variable before you try to call it.

Related

How do I use the value stored in a variable as a method call?

I have a method that looks like this:
> rating
=> "speed"
Then I have a call that looks like this:
profile.ratings.find_by(user: current_user).speed
What I want to do is pass the value of rating to that call.
But when I do this:
profile.ratings.find_by(user: current_user).rating
It doesn't work, because there is no method called rating on each ratings object.
This is the error I get when I run the above:
Rating Load (4.5ms) SELECT "ratings".* FROM "ratings" WHERE "ratings"."profile_id" = $1 AND "ratings"."user_id" = 7 LIMIT $2 [["profile_id", 12], ["LIMIT", 1]]
NoMethodError: undefined method `rating' for #<Rating:0x007fca0c4fba90>
I would normally do string interpolation, except now I am working on a method call.
How might I do this?
If you're looking to access a property on an ActiveRecord model they provide a simple accessor:
profile.ratings.find_by(user: current_user)[rating]
This is safer than the send method since it's only going to fetch attributes. If you had a method called ban_and_charge_ten_bucks! some hostile user might be able your system into calling that if you call send without checking what you're calling.
You can use the send method
profile.ratings.find_by(user: current_user).send(rating)

Can't pass the variable to subject in email laravel 5

Mail::send('emails.cont',['name'=>$n,'email'=>$email],function($message){
$message->to('abc#gmail.com','efe')->from('cde#gmail.com')->subject($s);
});
There for the subject, I am trying to pass a variable called $s which contains a value which defined there. But, it will underlying in red and saying undefined variable called $s. How to solve that?
can you please try the following code
Mail::send('emails.cont',['name'=>$n,'email'=>$email],function($message) use ( $s ) {
$message->to('abc#gmail.com','efe')->from('cde#gmail.com')->subject($s);
});

How to pass variables to page.executescript() in capybara

I need to pass the variable in the javascript to be executed through excute_script method in capybara.
I am unable to pass variable to it.
Please anyone help me.
Example:
#idd="sample"
txt=page.execute_script('var user_id = ${#idd}; return user_id;')
puts txt
I am expecting the text sample to be printed but i'm getting java script error.
I think the problem is with ${}; you have to use #{}; try with:
page.execute_script("var user_id = '#{#idd}'; return user_id;")

No Error for Undefined Variable Used in Class Methods in PHP

I spent more than 10 hours to find out the typo for debugging my PHP program. I expected PHP would produce an error when using an undefined variable. But when it is used as an object in a method, it doesn't. Is there a reason for it?
<?php
$oClass = new MyClass;
// $oCless->tihs('key', 'taht'); //<-- triggers the error: Notice: Undefined variable
$oClass->tihs('key', 'taht');
echo $oClass->arr['key'];
class MyClass {
public $arr = array('key' => 'foo');
function tihs($key, $value) {
$tihs->arr[$key] = $value; //<-- this does not cause an error message.
}
}
?>
Normally if the error reporting level is set to E_ALL | E_STRICT (or E_ALL as of PHP 5.4.0) it should spit out an E_STRICT error. For instance, this code:
error_reporting(E_ALL | E_STRICT);
$tihs->adrr = 453;
Produces:
Strict Standards: Creating default object from empty value in [...]
Interestingly enough, if you specifically create an array instead of an ordinary variable as a property of an object that doesn't exist, e.g.:
error_reporting(E_ALL | E_STRICT);
$tihs->adrr[25] = 453;
No strict standards error is shown! It looks like this could potentially be something PHP folks might want to fix, because I'm not aware this is documented nor I think there's a legitimate reason for this behaviour.
For the record, in both cases regardless of the error a new stdClass is being created on the fly instead, like sberry mentions in his answer.
It is because of PHP trickery...
Under the covers, PHP is actually creating an object called tihs, adding an array to the object called arr and setting key to value.
Here is a print_r($tihs); after the assignment:
stdClass Object
(
[arr] => Array
(
[key] => taht
)
)
You seemed to have misspelt $oClass as $oCless
Agreed, $oCless instead of $oClass would give you an undefined variable error.
Also, "this" is a keyword in most languages and may be in php as well. You should refrain from using it so that it doesn't come out in other languages as a habit. You'll get way more errors if you're using "this" as function and variable names. You wouldn't even get things to compile.

how to use object attribute value for method name ruby

I have a two mailers
welcome_manger(user) welcome_participant(user)
Both send different information and have different layouts.
when I call the deliver method I would like to use something like the following
UserMailer.welcome_self.role(self.user)
This does not work. How can I accomplish this?
Something like this perhaps:
m = 'welcome_' + self.role
UserMailer.send(m.to_sym, [self.user])
Assuming that self.role returns a String.
The send method invokes a method by name:
obj.send(symbol [, args...]) → obj
Invokes the method identified by symbol, passing it any arguments specified.
So you just need to build the appropriate method name as a string and then convert it a symbol with to_sym.

Resources