Equivalent of “pass” in Ruby - ruby

In python there is a pass keyword for defining an empty function, condition, loop, ...
Is there something similar for Ruby?
Python Example:
def some_function():
# do nothing
pass

No, there is no such thing in Ruby. If you want an empty block, method, module, class etc., just write an empty block:
def some_method
end
That's it.
In Python, every block is required to contain at least one statement, that's why you need a "fake" no-op statement. Ruby doesn't have statements, it only has expressions, and it is perfectly legal for a block to contain zero expressions.

nil is probably the equivalent of it:
def some_function
nil
end
It's basically helpful when ignoring exceptions using a simple one-line statement:
Process.kill('CONT', pid) rescue nil
Instead of using a block:
begin
Process.kill('CONT')
rescue
end
And dropping nil would cause syntax error:
> throw :x rescue
SyntaxError: (irb):19: syntax error, unexpected end-of-input
from /usr/bin/irb:11:in `<main>'
Notes:
def some_function; end; some_function returns nil.
def a; :b; begin; throw :x; rescue; end; end; a; also returns nil.

You always have end statements, so pass is not needed.
Ruby example:
def some_function()
# do nothing
end
Ruby 3.0
As of Ruby 3.0, so-called "endless" method definitions are now supported -- we no longer require end statements with every single method definition. This means the most concise way of expressing an empty method like the example above is now arguably something like this:
def some_function = nil
Alternatively, there has always been an uglier one-line option using the much-hated semicolon:
def some_function; end
Note that this doesn't really change anything about the first solution except how the code can be written.

Single line functions and classes
def name ; end
class Name ; end
works fine for pseudocode.
As answered before everything in ruby is an expression so it is fine to leave it blank.
def name
end
class Name
end
A ruby alternative for python programmers who love the pass keyword
def pass
end
# OR
def pass; end
Note that it is useless to do this in Ruby since it allows empty methods but if you're that keen on pass, this is the simplest and cleanest alternative.
and now you can use this function inside any block and it will work the same.
def name
pass
end
# OR
class Name
pass
end
Keep in mind that pass is a function that returns, so it is up to you how you can use it.

If you want to be able to use it freely with any number of arguments, you have to have a small trick on the arguments:
def gobble *args, &pr; end

As others have said, in Ruby you can just leave a method body empty. However, this could prove a bit different than what Python accomplishes with pass.
In Ruby, everything is an object. The absence of value, which some programming languages indicate with null or nil is actually an object of NilClass in Ruby.
Consider the following example (in irb):
class A
def no_op
end
end
A.new.no_op
# => nil
A.new.no_op.class
# => NilClass
A.new.no_op.nil?
# => true
Here's Ruby's NilClass documentation for reference.
I believe Python's pass is used mainly to overcome the syntactic limitations of the language (indentation), although I'm not that experienced in Python.

Ruby's equivalent to pass can be ().
if 1 == 1
()
else
puts "Hello"
end
=> nil
lambda do
()
end.call
=> nil
You can also use it as part of condition ? true-expr : false-expr ternary operator.

Related

How do write two methods with different number of arguments in Ruby

I am trying to write this inside my class:
class << self
def steps
#steps.call
end
def transitions
#transitions.call
end
def steps(&steps)
#steps = steps
end
def transitions(&transitions)
#transitions = transitions
end
end
That won't work since in Ruby, I can't do this kind of method overloading. Is there a way around this?
You can kind of do this with method aliasing and mixins, but the way you handle methods with different signatures in Ruby is with optional arguments:
def steps(&block)
block.present? ? #steps = block : #steps.call
end
This sort of delegation is a code smell, though. It usually means there's something awkward about the interface you've designed. In this case, something like this is probably better:
def steps
#steps.call
end
def steps=(&block)
#steps = block
end
This makes it clear to other objects in the system how to use this interface since it follows convention. It also allows for other cases, like passing a block into the steps method for some other use:
def steps(&block)
#steps.call(&block)
end
Ruby does not support method overloading (see "Why doesn't ruby support method overloading?" for the reason). You can, however, do something like:
def run(args*)
puts args
end
args will then be an array of the arguments passed in.
You can also pass in a hash of options to handle arguments, or you can pass in nil when you don't want to supply arguments and handle nil in your method body.

Ruby ArgumentError trapping

Given a class:
class Foo
def initialize(input1)
#input1 = input1
end
end
is there some way that would throw a more helpful error against a = Foo.new()? How can I build a method that throws an ArgumentError in a more helpful way?
I'd like to build this into the class. The Programming Ruby site lists several error-trapping mechanisms, but all of these seem to depend on wrapping a = Foo.new() in a catch block or the like. I would like to have my error trapping within the class itself however.
Since you're new to Ruby it's understandable this error might seem odd, yet it's also an error that's very specific to passing the wrong arguments in. Remapping it to something else isn't necessarily helpful, it ends up hiding problems in your code. I'd suggest leaving it as-is and expecting errors like that to occur if you're not calling it correctly.
The alternative is, at least in newer versions of Ruby, to declare keyword arguments with no defaults:
def initialize(input1:)
end
That's a required keyword argument, and the error is more specific:
ArgumentError: missing keyword: input1
The downside is you have to call it like this:
Foo.new(input1: 'test')
That might be beneficial in terms of clarity. It's up to you.
you can use a default value and raise whatever error you need within the initialize method for example
Class A
def initialize(a = nil)
raise("give me an A") if a.nil?
#a = a
end
end
You can do this pretty simply by raising that error when the argument is not defined. You can add a message to the ArgumentError exception by specifying it as an argument on the exception:
class Foo
def initialize(input1=nil)
raise ArgumentError, "expected a value for Foo.new('value')" unless input1
#input1 = input1
end
end
After reading Programming Ruby a bit more, I think using alias_method as a hook might serve:
alias_method :initialize_orig, :initialize
def initialize(*args)
begin
result = initialize_orig(*args)
return result
rescue Exception
$stderr.print "Need to use argument 'input1'\n"
raise
end
end

Initialization idiom in ruby

There seems to be this initialization idiom in the ruby world where you do
def initialize(*someargs)
#begin initialization
yield self #so that the user can customize writable attributes
#finish initialization
end
and the user then does:
some_object = SomeClass.new do |o|
o.attribute1 = 'foo'
o.attribute2 = 'bar'
end
The Rake TestTask uses this, for example.
Is there any point in continuing this now that ruby has keyword arguments?
Standard arguments could have easily replaced this idiom, but positional arguments are inconvenient to the user when there's many of them, and a hash argument is inconvenient to the developer as he or she would have to check for valid keys. The above idiom seemed to eliminate both inconveniences, but keyword args do too and additionally they eliminate the need for a block and a repeated yielded_something. initialization pattern.
E.g.:
class SomeClass
def initialize(attribute1: nil, attribute2: nil)
end
end
SomeClass.new(
attribute2: 'bar',
attribute1: 'foo'
)
#Order doesn't matter like with the block idiom
#Invalid keys raise an error, just like invalid attribute assignments in the block idiom
Is this correct or am I missing something?
I think before keyword arguments, just passing a hash of options would have been fine, so I don't think arguments were the issue. Probably this type of instantiation was done for readablity and flexibility.
It makes it much easier to read config options when written like this. And also it makes it easier to do something like this:
Config.new do |c|
c.default_address = c.default_address + "/new"
end
The block syntax allows the user to add their own logic and call methods within the class which is especially useful for configuration objects.
For instance, RSpec's configuration object allows you to do something like:
RSpec.configure do |config|
config.before :each do
# do something before each test
end
end
This particular example isn't performed in the initializer, but depending on use case it could very well be.

Ruby switch like idiom

I have recently started a project in Ruby on Rails. I used to do all my projects before in Python but decided to give Ruby a shot.
In the projects I wrote in Python I used a nice little technique explained by the correct answer in this post:
Dictionary or If statements, Jython
I use this technique due to Python not having a native switch function and it also get rid of big if else blocks
I have been trying to do recreate the above method in Ruby but can't seem to quite get it.
Could anyone help me out?
If you only need to call a method by its name stored in a string, standard Ruby way of doing it is using method Object#send:
def extractTitle dom
puts "title from #{dom}"
end
def extractMetaTags dom
puts "metatags from #{dom}"
end
dom = 'foo'
type = 'extractTitle'
send type, dom
#=> title from foo
type = 'extractMetaTags'
send type, dom
#=> metatags from foo
Otherwise, you can use Ruby's case statement, as already suggested.
While nothing prevents you from using the class-based approach, why avoid rubys case statement?
case thing
when 'something'
do_something
when 'nothing'
do_nothing
else
do_fail
end
As others have said, there are alternative ways of doing this in Ruby, but if you are just curious then an equivalent to that Python approach in Ruby (making use of Object#send once you have determined the method name) would be:
class MyHandler
def handle_test(arg)
puts "handle_test called with #{arg}"
end
def handle_other(arg)
puts "handle_other called with #{arg}"
end
def handle(type, *args)
method_name = "handle_#{type}"
if respond_to? method_name
send(method_name, args)
else
raise "No handler method for #{type}"
end
end
end
You can then do:
h = MyHandler.new
h.handle 'test', 'example'
h.handle 'other', 'example'
h.handle 'missing', 'example'
and the output would be:
handle_test called with example
handle_other called with example
handle.rb:15:in `handle': No handler method for missing (RuntimeError)
from handle.rb:23

Mass assignment on construction from within ruby [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Idiomatic object creation in ruby
Sometimes it's useful to assign numerous of a constructed arguments to instance variables on construction. Other than the obvious method:
def initialize(arg1, arg2, arg3)
#arg1, #arg2, #arg3 = arg1, arg2, arg3
end
Is there a more concise idiom for achieving the same result? Something like that found in scala for instance:
class FancyGreeter(greeting: String) {
def greet() = println(greeting)
}
Where in this case the object FancyGreeter has a default constructor that provides assignment for it's passed arguments.
In Ruby 1.8, block arguments and method arguments have different semantics: method arguments have binding semantics, block arguments have assignment semantics.
What that means is that when you call a method, the method arguments get bound to the values that you pass in. When you call a block, the values get assigned to the arguments.
So, you can create some pretty crazy looking blocks that way, that seemingly don't do anything:
lambda {|#a|}.call(42)
The block body is empty, but because of the argument assignment semantics, the instance variable #a will be assigned the value 42. It works even crazier:
lambda {|foo.bar|}.call(42)
Yes, attr_writer methods work too. Or what about
foo = {}
lambda {|foo[:bar]|}.call(42)
p foo # => {:bar => 42}
Yup, those too.
And since you can define methods using blocks, you can do this:
class FancyGreeter
define_method(:initialize) {|#greeting|}
def greet; puts #greeting end
end
or even
class FancyGreeter
attr_accessor :greeting
define_method(:initialize) {|self.greeting|}
def greet; puts greeting end
end
However, I wouldn't recommend this for two reasons:
Not many Rubyists know this, be kind to the people who have to maintain the code after you.
In Ruby 1.9 and onwards, block argument semantics are gone, blocks also use method argument semantics, therefore this does no longer work.
I suppose you could do....
def initialize *e
#a, #b, #c = e
end
I don't know about "better" but there are varying levels of 'clever':
def initialize args={}
args.each do |key, value|
instance_variable_set "##{key}", value
end
end
But "clever" is usually dangerous when you program :-)
Edit: Given the edited question, I'll add this:
Class PickMe
def initialize say="what?"
#say = say
end
end
Just because I don't know if you're aware of default options. Otherwise, think of the value of self-documenting code. A cleanly-written 'initialize' method is priceless.
It was either Andy Hunt or Dave Thomas who proposed that Ruby should be able to handle this syntax for initializing member variables from constructor arguments:
def initialize(#a, #b, #c)
...
end
Matz did not accept their proposal; I don't remember why.

Resources