Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
Can someone please give me a simple example of using ARGV in a method in ruby, i just need to understand it better, i have tried using
def greet(ARGV)
puts "Hello #{ARGV}"
end
TL;DR
Don't use constants to collect method arguments, especially special constants like ARGV. Use positional or collected-positional arguments instead.
Using ARGV Generally Implies Command-Line Arguments
ARGV is a predefined global constant in Ruby. You can think of it as an Array of String values that contain the arguments passed to the Ruby interpreter, but while you technical can redefine it at runtime you should not be doing that in most cases, and certainly not redefining a global constant as part of a method definition.
ARGV[0] is the name of the file passed to the interpreter (similar to Bash's $0) while anything else is a positional parameter like Bash's positional arguments of $1 to $9. You can also get at ARGV through ARGF#argv, but that's not your use case here.
Passing Positional Arguments to a Method
If you want to pass a single argument to a method, just give it a non-constant name. For example:
def greet(name)
puts "Hello, #{name}!"
end
If you really want to pass a variable number of arguments to a method as a named Array, then you can do that, too. For example:
def greet(*names)
names.each { |name| puts "Hello, #{name}!" }
end
%w[Alice Bob Carol].map { |name| greet(name) }
In this case, you're collecting a list of names the method-local Array names, and then iterating over the items in that Array. There are some edge cases with this that are outside the scope of your original question such as empty arrays, nil values, and passing Array objects as positional arguments, but again those edge cases are outside the scope of your original question.
Summary
Use ARGV if you're passing arguments on the command line. Otherwise, use positional arguments or collected-Array arguments in your method definitions.
try this
def greet(name)
"Hello #{name}"
end
puts greet(ARGV[0])
when you run in the terminal you enter file_name.rb user# then you enter your argument before running the file and you will get something like Hello user
Related
This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 4 years ago.
I've seen an example of how to sort a string. To sort case insensitively:
str.chars.sort(&:casecmp).join
#=> "ginrSt"
I'm curious about (&:casecmp). I found that for example:
arr.map(&:name)
is shorthand for
arr.map(&:name.to_proc)
which is same with
arr.map{|el| el.name}
I know the & (ampersand) tries to convert symbol to proc, and pass it as a block to a method. I do not understand how this would work for sort method, which is supposed to compare two values. Would it be as follows?
str.chars.sort{|a, b| a.casecmp ;b.casecmp}.join
It wouldn't be helpful since soft needs a block to return an integer and casecmp needs an argument. (Or is it called parameter in that case?) To me, it looks more like this:
str.chars.sort{|a, b| a.casecmp(b)}.join
How does &:casecmp know to take one of |a, b| as a caller and the other one as an argument? I wouldn't guess it that it is an option.
If more than one parameter is passed to your block, the proc created by Symbol#to_proc uses the additional block parameters as parameters to the method call.
http://phrogz.net/symbol-to-proc-with-multiple-arguments
So, what's really happening is, sort(&:casecmp) is converted to:
sort {|a,b| a.casecmp(b) }
because sort takes two parameters.
This question already has answers here:
Ruby Print Inject Do Syntax
(3 answers)
Closed 7 years ago.
Let's say I have the following (working) pseudo-code:
puts results.fields.inject('') { |string, key|
lengths[key] = calculate_length(key)
string << format(key)
}
Following the ruby-style-guide I should
Omit parentheses for 'keyword methods', i.e. puts, (which would create }) or end) anyway)
Use do...end for multi-line blocks
However, when replacing {...} with do...end it raises
undefined method `' for :title:Symbol (NoMethodError)
Therefore, is it possible to refactor this code without violenting the guideline?
There is a difference in precedence between {} and do end
If you use do end the block is associated with the puts statement, whereas the braces are associated with the results.field.inject('')
If you want to use do end then you have to remove the ambiguity of association by parentheses. It's one of those "gotchas" where the guidelines are recognized as guidelines, not absolute rules.
See also this answer...
In Ruby, why is a method invocation not able to be treated as a unit when "do" and "end" is used?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a class called Polynomialthat is overriding Array. I need to check that the array being passed to it on Polynomial.new([]) has at least 2 args.
I was thinking something like the following, but it's causing weird behavior in my tests.
class Polynomial < Array
def initialize(coefficients)
if coefficients.size < 2
puts "you need to have more than 1 arg"
else
self = coefficients
end
end
If you insist on keeping Polynomial an Array (I agree with #matt that this is probably a bad idea) then you still should call #super in your initialize, at least if all is well. Given you would like to be given an array as the argument list you might resort to a splat argument which will always turn out to be an array. But since you asked I will include the check in my example code:
class Polynomial < Array
def initialize(*coeffs)
if coeffs.is_a? Array
coefficients=coeffs.flatten
if (coefficients.size < 2)
puts "you need to have more than 1 arg"
else
super(coefficients)
end
else
puts "you need to give me an array"
end
end
end
This checks if your argument is an array (which it always will be because of the splat). Ruby methods tend to be generous about the "things" you can throw at them, so this methods calls #flatten on your args list in order to allow both versions:
p1=Polynomial.new([1,2])
=> [1, 2]
p2=Polynomial.new(1,2)
=> [1, 2]
It checks your condition of at least 2 elements, but you would probably like to add additional conditions such as all of your arguments should be numerical (as it is you can have any Object in your coeffs, but you probably only want Numeric, another reason not to subclass Array). You may add more conditions as you see fit.
This is how a method can know how many arguments it received when called:
def meth(*args)
puts args.length
end
So you might like to design Polynomial to receive a variable number of arguments in its initializer, instead of an array of arguments, and then use *args to set the contents of the array. (I am not convinced, by the way, that Polynomial should be an array; one rather expects it to have an array...)
This question already has an answer here:
naked asterisk as parameter in method definition: def f(*)
(1 answer)
Closed 8 years ago.
In the rails code I came across following method definition def initialize(*)
I understand what def foo(*a) means but can't figure out significance of omitting identifier name after *. How do you access any arguments passed to this method?
Here's my guess.
It works because of second line:
def initialize(*)
super
...
end
So the method receives arbitrary number of arguments and passes all of them to super(as you know, super without arguments means take all arguments from original method).
And then in this case the names for arguments are not required.
I'm starting to learn Ruby. I read that arguments where passed by reference to a method,
however I don't understand the difference between these two methods.
def print(text)
puts text
end
and
def print(*text)
puts text
end
Using a * means that we are passing a pointer like in C?
The *text is what's called the splat operator in Ruby. It basically means if you pass multiple arguments to the second print they will get slurped into the single text variable.
See The Splat Operator in Ruby
The * before a parameter name in a Ruby parameter list is used for variable length arguments, so they are similar to the ... in C/C++ for varargs.
def vlaFunc(*args)
puts args
end
vlaFunc(1,2,3)
# output is [1,2,3]
There are no pointers in Ruby, * in this context is generally referred to as the "splat" operator:
http://4loc.wordpress.com/2009/01/16/the-splat-operator-in-ruby/
http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/
In this case the method can take an arbitrary number of arguments, which will be available in the array text.
First you have two nice methods started there. But I would say try to avoid using puts inside them. You don't need it anyway. A method will always yield the last statement evaluated. something = text would get the job done. And I don't need to answer now about the differences.
Your first two replies are very good there. But you may want to try something like this
j = *[] #=> nil in 1.8 but [] in 1.9
It's been the new kid on the block for a time now. Guess what it does?