How to pass by value when dealing with rails associations - ruby

I'm a newbie, working with Rails. I'm trying to reassign an invitation object from one user to another user. Here's the controller
def create
#invitation = Invitation.new(invitation_params)
#trip = Trip.find(params[:trip_id])
#invitation.trip = #trip
#invitation.attributes = {user: #trip.user, status: "Pending"}
authorize #invitation
if #invitation.save
InvitationMailer.with(email: params[:invitation][:email], invitation: #invitation, trip: #trip).invite_email.deliver
redirect_to trip_path(#invitation.trip)
else
render :new
end
def accept
#invitation.attributes = {user: current_user, status: "Accepted"}
if #invitation.save
redirect_to trip_path(#invitation.trip)
end
Problem is, when dealing with objects, passing by reference seems to be the only option. I can't reassign the #invitation.user without also overwriting #trip.user with current_user.
Thanks in advance.

Problem is, when dealing with objects, passing by reference seems to be the only option.
Ruby is always pass-by-value, with no exceptions. It does not support pass-by-reference at all. The only mainstream languages I can think of right now that do support pass-by-reference are C++ (with the & sigil / operator), C# (with the ref keyword), PHP (&), and Perl. In C++, C#, and PHP, the default is pass-by-value, and you have to explicitly ask for pass-by-reference. Perl is the only one where pass-by-reference is the default, and in fact not just the default but the only option.
So, to repeat: Ruby is always pass-by-value. It is impossible to achieve pass-by-reference in Ruby. The semantics of the language just do not allow it. You would have to modify the language itself and change the interpreter/compiler (or write a new one), in which case it is no longer Ruby.
It is not quite clear from your code what, precisely, is going on, but one thing is 100% sure: pass-by-reference cannot possibly be the problem. You can stop investigating that avenue.

Related

is it best practice to define vars first before using them inside a begin block?

foo = ''
begin
foo = 'hi there'
rescue
end
puts foo
if I don't delcare foo = '' at the top before the begin it still works. But I see a lot of people do this. And it feels better. But is it best practice?
This is part paranoia, and part clarity. In this trivial example there's unlikely to be an issue, but what if you had this?
begin
foo = complicated_method_call(with: lots_of_arguments, and: another_call(with: args))
rescue
end
A whole bunch of stuff could go wrong there, and if that's the case you end up with foo being nil.
Now, using a blind rescue is generally bad form, you ideally want to scope down to just the ones your code might trigger.
Remember Ruby variables are defined at the method level, any instance of them in the method makes them defined, but they will have a default of nil which can be undesirable.
As you already know, for Ruby the variable exists whenever you assign a value/object to it, making it a weakly/loosely-typed (as opposed to "strongly typed") language. Why? The focus of the language's designer was simplicity and easy of use -- see the statement in the manual :). Remember also that there isn't a need to write 'return' inside methods to return values nor write parenthesis when calling functions if there isn't confusion. Why? Simplicity, ease of use. Hard to tell if these things are better or not as a general answer. Do we have to rely always upon the compiler checks? Are we pro? Really? But generally speaking, we can hardly find ruby programmers declaring variables always unless instance/global ones, and at the end we'll getting ourselves rushing in the mainstream. Yay! General answer to determine the type of a variable: https://en.wikipedia.org/wiki/Duck_test Have fun!

Is it good practice having local variables starting with underscore?

I'm just getting into Ruby and come from the Java and C/C++ environment.
While coding a first little project in Ruby, I somehow got used to let all local variables start with an underscore. I guess my main motivation for this was a better readability and distinction from method calls.
As in principle there are only three types of variables ($global, #instance and local), the vast majority of variables start with an underscore. I'm not really sure, whether this is good or bad. Besides, in a lot other languages, the underscore would be substituted to some other character.
Is there somehow a best practice concerning variable naming beside the usual CamelCase and/or underscore separated? What are the habits of the professional "rubyists"? Have I overlooked some general Ruby conventions, when I chose the leading underscore?
edit
Thanks to all answers and suggestions. It helped me a lot.
Short Summary of Answers and Comments below
(for the short-on-time visitor)
Leading underscores go with:
method arguments: def my_method(_my_arg)
block arguments: e.g. my_array.each { |_x| puts _x}
All other local variables without leading underscores, as programmers coming from e.g. JavaScript might get confused about intended behaviour of the variables.
For visual separation between variable names and method calls, forcing oneself to use "(" brackets ")" with all method calls might increase readability significantly.
Existing answers to this question are now a few years old, and conventions have changed. You should only ever use a leading underscore (_some_param), or a standalone underscore (_), to indicate that you don't care about the value. The rubocop style linting tool will carp about a "useless assignment" if you assign a variable but don't use it, but it will ignore variables with a leading underscore. This allows you to expressly indicate that you don't care about the value and don't intend to use it.
Here's a somewhat-contrived example use-case in an RSpec context:
describe 'login' do
let(:user) { FactoryGirl.create(:user, login: 'bob') }
it 'must be unique' do
_user1 = user
user2 = User.new login: 'bob'
expect(user2.valid?).to be_false
end
end
Here we're indicating that our user helper has a side-effect and returns something, but we don't care about it. You could also just skip the assignment entirely, but seeing a bare user on a line by itself looks odd and doesn't reveal the intention as clearly:
describe 'login' do
let(:user) { FactoryGirl.create(:user, login: 'bob') }
it 'must be unique' do
user
user2 = User.new login: 'bob'
expect(user2.valid?).to be_false
end
end
Other scenarios include ignoring values in iterators, or overriding a method where you want to keep the original method signature but don't care about some of the values:
def greet(name, _title)
puts "Hi, #{name}!"
end
In my experience, underscore-prefixed variables in Ruby are much like underscore-prefixed variables in JavaScript: a "don't touch" flag. More specifically, they are used when the implementer is doing something that really is not supposed to be understood as a part of the object, or shouldn't be thought of as the conceptual interface of the object.
This is more clear in the JavaScript world, where somebody is emulating "private" by prefixing a variable with an underscore. They are encoding that there's part of the object that's under the hood and can be ignored when looking at the object from the outside.
In Ruby, I've only really seen this with things like a cache or a singleton instance - the kind of thing that should be invisible to consumers of your object. Non-underscored variables are things that people using your object might be interested to know are there.
In any case, they seem fairly rare, and I would avoid them unless you want to send a signal to the next guy that's coming along that there's some extra magic or voodoo happening.
As far as making a distinction for method calls, if you're worried that there can be confusion between a method and a local variable, I would call the method on self to clarify. For instance:
def foo
...
end
def some_method
foo # method
bar # variable
end
If this seems unclear for whatever reason, you can clarify with
def some_method
self.foo
bar
end
Nothing wrong with your idea. But if I was having trouble distinguishing local vars from method calls, I would probably just force myself to always use ()'s on methods. (My team at work has discussed making this part of our coding standards).
a = thing # var
b = thing() # method
The possible advantage to this is readability to others. Someone may wonder at your leading _'s, but using ()'s on all method calls should be clear to everyone.
Seeing as how instance variables have the # sign in front of them, and global variables have the $ sign in front of them already in ruby, it is probably unnecessary to put an underscore character in front of the variable names. That being said, I don't think it is a bad practice necessarily. If it helps you to read or write your code in Ruby, then you should use it.
I have sometimes seen Ruby code where an argument for an instance method on a class has an underscore in front of it. Such as:
def my_method(_argument1)
# do something
end
And I think that when you are dealing with a class that may have it's own attributes, like a model file in rails, for instance, this can be helpful so that you know you are dealing with a variable that has been passed into the method as opposed to one of the attributes that belongs to the class/model.

How can I splattify an anonymous object so I can use &method on it?

I'm wanting to use the &method(:method_name) idiom when there's more than one object required by method_name. Can I do this under Ruby 1.9?
For example, if I've got
def move_file(old_filename, new_filename)
STDERR.puts "Moving #{old_filename.inspect} to #{new_filename.inspect}"
# Implementation for careful moving goes here
end
old_filenames = ["foo.txt", "bar.txt", "hoge.ja.txt"]
new_filenames = ["foo_20110915.txt", "bar_20110915.txt", "hoge_20110915.ja.txt"]
the code
old_filenames.zip(new_filenames).each(&method(:move_file))
works under Ruby 1.8, but not under Ruby 1.9. Under Ruby 1.9, it's trying to do move_file(["foo.txt", "foo_20110915.txt"]) instead of move_file("foo.txt", "foo_20110915.txt").
How do I splattify it so it has the correct arity?
Workarounds I'm aware of:
Replace def move_file(old_filename, new_filename) with def move_file(*arguments)
Replace each(&method(:move_file)) with
each{|old_filename, new_filename| move_file(old_filename, new_filename)}
Instead
each{|old_filename, new_filename| move_file(old_filename, new_filename)}
you should be able to do
each{|pair| move_file(*pair)}
But I don't know how you'd pull off blockless variant (I needed it couple of times as well). I guess &-shorthand was made to make the syntax simpler, and is not meant to be clogged much (whether it will be passed an array as an array, or splatted, for example). :)
How do I splattify it so it has the correct arity?
I don't think there is a way to do this while being compatible to both Ruby versions. What you could do is wrap it into a lambda
move_from_to = Proc.new {|*both| move_files(*both) }
The thing is - block and proc arity is something that got addressed in Ruby 1.9 so there might be a difference in behavior there. Also see prc.lambda? here http://www.ruby-doc.org/core/classes/Proc.html for info on what it does to the arity.
This question is also related to what you want to do (the solution there is to resplat and unsplat manually): Inconsistency of arity between Hash.each and lambdas

Plain Old Objects in Ruby?

I notice in Ruby it is very common to for vendor APIs to pass back results as arrays? Shouldn't Plain Old Objects (Like POJOs in Java) be more of a standard? If I write my own library shouldn't I use POJOs POROs?
I think array vs object is a false dichotomy.
It is perfectly reasonable, where an API call is returning more than one of a thing, that it is in the form of an array (and an array is a fairly simple object, and therefore arguably a 'PORO', in Ruby anyway)
Edit: in response to your comments:
The example you cite ( http://github.com/cjheath/geoip ) returns an array of differing items. I agree this is not necessarily the best format to return the data in. In that case I would have thought a hash with sensibly named keys would be a better structure.
As John Topley says, the OO nature of Ruby means people don't have to invent such terminology as 'PORO', as a hash is pretty much as simple as you can get.
It's all objects, all the time. The key is whether the objects being returned have behavior associated with them. It's fine to do this:
def read_first_and_last_name(data_source)
[data_source.read_string, data_source.read_string]
end
But the moment you find there is behavior associated with those data items...
def print_name(first_name, last_name)
puts "#{first_name} #{last_name}"
end
def read_and_print_name
first_name, last_name = read_first_and_last_name(data_source)
print_name(first_name, last_name)
end
...then they should be a class:
class FullName
def FullName.read(data_source)
FullName.new(data_source.read_string, data_source.read_strng)
end
def initialize(first_name, last_name)
#first_name = first_name
#last_name = last_name
end
def print
puts "#{#first_name} #{#last_name}"
end
end
With a name's behavior nicely encapsulated, usage becomes as simple as:
def read_and_print_name
FullName.read(data_source).print
end
What do those arrays of results contain? The answer is that in Ruby they contain objects, because everything in Ruby is an object.
POJOs in the Java world were a reaction against some of the complexities inflicted upon the world by enterprise Java e.g. EJBs. To quote Martin Fowler who coined the term:
"We wondered why people were so
against using regular objects in their
systems and concluded that it was
because simple objects lacked a fancy
name. So we gave them one, and it's
caught on very nicely."
Fortunately in Ruby it has always been natural for people to just practise object-oriented programming without the need to invent terminologies around it.
I personally use POROs in almost anything I write that isn't a complete throwaway script.
I find myself often creating a data holder type of class that would manage and hold multiple objects of my specific type and include some helper methods. I find this convenient for when someone else has to work with my code as well.
I think this question is very subjective in the sense that there isn't an answer that is always right. Sometimes just passing back an array is fine and there is no need to create an extra class. Sometimes the extra level of abstraction makes something a lot more clear to the user.

When is `eval` in Ruby justified?

"Is 'eval' supposed to be nasty?" inspired this one:
Mostly everybody agrees that eval is bad, and in most cases there is more elegant/safer replacement.
So I wanted to ask: if eval is misused that often, is it really needed as a language feature? Is it doing more evil than good?
Personally, the only place I find it useful is to interpolate strings provided in config file.
Edit: The intention of this question is to get as many real-life cases as possible when eval is the only or the best solution. So please, don't go into "should a language limit a programmer's creativity" direction.
Edit2: And when I say eval, of course I refer to evaling string, not passing ruby block to instance_eval or class_eval.
The only case I know of (other than "I have this string and I want to execute it") is dynamically dealing with local and global variables. Ruby has methods to get the names of local and global variables, but it lacks methods to get or set their values based on these names. The only way to do AFAIK is with eval.
Any other use is almost certainly wrong. I'm no guru and can't state categorically that there are no others, but every other use case I've ever seen where somebody said "You need eval for this," I've found a solution that didn't.
Note that I'm talking about string eval here, by the way. Ruby also has instance_eval, which can take either a string or a block to execute in the context of the receiver. The block form of this method is fast, safe and very useful.
When is it justified? I'd say when there's no reasonable alternative. I was able to think of one use where I can't think of an alternative: irb, which, if you dig deep enough (to workspace.rb, around line 80 in my copy if you're interested) uses eval to execute your input:
def evaluate(context, statements, file = __FILE__, line = __LINE__)
eval(statements, #binding, file, line)
end
That seems pretty reasonable to me - a situation where you specifically don't know what code you're going to have to execute until the very moment that you're asked to do so. Something dynamic and interactive seems to fit the bill.
The reason eval is there is because when you need it, when you really need it, there are no substitutes. There's only so much you can do with creative method dispatching, after all, and at some point you need to execute arbitrary code.
Just because a language has a feature that might be dangerous doesn't mean it's inherently a bad thing. When a language presumes to know more than its user, that's when there's trouble.
I'd argue that when you find a programming language devoid of danger, you've found one that's not very useful.
When is eval justified? In pragmatic terms, when you say it is. If it's your program and you're the programmer, you set the parameters.
There is one very important use-case for eval() which cannot (AFAIK) be achieved using anything else, and that is to find the corresponding object reference for a binding.
Say you have been passed a block but (for some reason) you need access to object context of the binding, you would do the following:
obj = eval('self', block.binding)
It is also useful to define the following:
class Proc
def __context__
eval('self', self.binding)
end
end
IMO mostly for Domain Specific Languages.
"Evaluation Options in Ruby" is an article by Jay Fields about it on InfoQ.
eval is a tool, it is neither inherently good nor evil. It is justified whenever you are certain it is the right tool for what you are trying to accomplish.
A tool like eval is about evaluating code at runtime vs. "compile" time. Do you know what the code is when you launch Ruby? Then you probably don't need eval. Is your code generating code during runtime? then you probably need to eval it.
For example, the methods/functions needed in a recursive decent parser depend on the language being parsed. If your application builds such a parser on-the-fly, then it might make sense to use eval. You could write a generalized parser, but it might not be as elegant a solution.
"Programatically filling in a letrec in Scheme. Macros or eval?" is a question I posted about eval in Scheme, where its use is mostly unavoidable.
In general eval is a useful language feature when you want to run arbitrary code. This should be a rare thing but maybe you are making your own REPL or you want to expose the ruby run-time to the end user for some reason. It could happen and that is why the feature exists. If you are using it to work around some part of the language (e.g. global variables) then either the language is flawed or your understanding of the language is flawed. The solution is typically not to use eval but to either better understand the language or pick a different language.
It's worth noting that in ruby particulary instance_eval and class_eval have other uses.
You very likely use eval on a regular basis without even realizing it; it's how rubygems loads the contents of a Gemspec. Via rubygems/lib/specification.rb:
# Note: I've removed some lines from that listing to illustrate the core concept
def self.load(file)
code = File.read(file)
begin
_spec = eval code, binding, file # <-------- EVAL HAPPENS HERE
if Gem::Specification === _spec
return _spec
end
warn "[#{file}] isn't a Gem::Specification (#{_spec.class} instead)."
rescue SignalException, SystemExit
raise
rescue SyntaxError, Exception => e
warn "Invalid gemspec in [#{file}]: #{e}"
end
nil
end
Typically, a gem specification would look like this:
Gem::Specification.new do |s|
s.name = 'example'
s.version = '0.1.0'
s.licenses = ['MIT']
s.summary = "This is an example!"
s.description = "Much longer explanation of the example!"
s.authors = ["Ruby Coder"]
s.email = 'rubycoder#example.com'
s.files = ["lib/example.rb"]
s.homepage = 'https://rubygems.org/gems/example'
s.metadata = { "source_code_uri" => "https://github.com/example/example" }
end
Note that the gemspec file simply creates a new object but does not assign it nor send it anywhere.
Trying to load or require this file (or even executing it with Ruby) will not return the Gem::Specification value. eval is the only way to extract the value defined by an external ruby file.
One use of eval is compiling another language to ruby:
ruby_code = "(def foo (f a b) (mapv f (cons a b)))".compile_to_ruby
# "foo_proc = ->(f a b) { mapv_proc.call(f, (cons_proc.call(a, b)) }"
eval ruby_code
I use a 3D modeling software that implemented Ruby for writing custom text macros. In that software we are given access to model data in the form of name:value pairs accessed using the following format:
owner.name
#=> value
So for a 36 inch tall cabinet, I could access the height and convert its value to feet like so:
owner.height.to_f / 12
The main problem is that objects in that software have no unique identifiers aside from something called their schedule_number. If I want to name a variable using the schedule_number in the variable name so that I can call and use that value elsewhere, the only possible way I know to do that is by using eval:
eval "#{owner.schedule_number} = owner.height"

Resources