What Is a More Ruby-Like Way of Doing This Command

What is a more Ruby-like way of doing this command?

Since this code is in your controller, then it can definitely be refactored. You typically want logic like this to be in the models since it's easy to write unit tests and it's not the job of the controller to know so much about the user model.

There's a few ways you could refactor this, but I would recommend moving the logic to the user model like so:

def User < ActiveRecord::Base
def sender_email
paypal_email if paypal_email == "paypal@anonymous.com"
end
end

Then your controller wouldn't need to know as much and could just do:

sender_email = @request.user.sender_email

More ruby-like solution to this problem?

Rather than solve the problem in one go, looking at the individual parts of the problem might help you understand ruby a bit better.

The first part is finding out what the triangle number would be. Since this uses sequence of natural numbers, you can represent this using a range in ruby. Here's an example:

(1..10).to_a => [1,2,3,4,5,6,7,8,9,10]

An array in ruby is considered an enumerable, and ruby provides lots of ways to enumerate over data. Using this notion you can iterate over this array using the each method and pass a block that sums the numbers.

sum = 0
(1..10).each do |x|
sum += x
end

sum => 55

This can also be done using another enumerable method known as inject that will pass what is returned from the previous element to the current element. Using this, you can get the sum in one line. In this example I use 1.upto(10), which will functionally work the same as (1..10).

1.upto(10).inject(0) {|sum, x| sum + x} => 55

Stepping through this, the first time this is called, sum = 0, x = 1, so (sum + x) = 1. Then it passes this to the next element and so sum = 1, x = 2, (sum + x) = 3. Next sum = 3, x = 3, (sum + x) = 6. sum = 6, x = 4, (sum + x) = 10. Etc etc.

That's just the first step of this problem. If you want to learn the language in this way, you should approach each part of the problem and learn what is appropriate to learn for that part, rather than tackling the entire problem.

REFACTORED SOLUTION (though not efficient at all)

def factors(n)
(1..n).select{|x| n % x == 0}
end

def triangle(n)
(n * (n + 1)) / 2
end

n = 2

until factors(triangle(n)).size >= 500
puts n
n += 1
end

puts triangle(n)

What is the most Ruby-like way of generating every unique combination of 3 positive integers that add up to 100

I'd write:

(0..100).flat_map { |x| (0..100-x).map { |y| [x, y, 100-x-y] } }
#=> [[0, 0, 100], [0, 1, 99]], ..., [99, 1, 0], [100, 0, 0]]

Site note 1: this is a classical example where list-comprehensions shine (and even more if there were a condition somewhere). Since Ruby has no LC we have to do the typical conversion to OOP: N-1 flat_map's + 1 map. It would be awesome to have LCs in Ruby (check this feature request), Scala has proven that even a pure OOP language greatly benefits from this syntactic sugar (though I can understand prevention from the devs because of the implicit iterable protocol/method). On an imaginary Ruby that supported them you'd write:

[[x, y, 100-x-y] for x in 0..100 for y in 0..100-x] # imaginary Ruby

Side note 2: Imagine that you prefer a less memory-consuming solution (you probably don't need the whole array). A lazy solution with Ruby 2.0 requires just to add a couple of [lazy][2] proxies:

(0..100).lazy.flat_map { |x| (0..100-x).lazy.map { |y| [x, y, 100-x-y] } }

Side note 3: Just for completeness, in the line of @akuhn answer, another lazy solution using enumerators:

Enumerator.new do |e| 
(0..100).each { |x| (0..100-x).each { |y| e.yield([x, y, 100-x-y]) } }
end

Ruby-like Syntax Highlighting in VIM for Thor

au BufRead,BufNewFile *.thor set filetype=ruby

I think should suffice... maybe this if you want to customize it later:

au BufRead,BufNewFile *.thor set filetype=thor
au! Syntax thor source $HOME/.vim/syntax/thor.vim

and copy ruby .vim syntax highlight file to $HOME/.vim/syntax/thor.vim

Ruby (Rails) Delegate attributes to another model's method?

So what you are asking is that

photo.file       --> photo.attachment.file
photo.file.url --> photo.attachment.file.url
photo.file.width --> photo.attachment.width

You can't solve this with delegates, because you want that file to mean different things based on what follows next. To achieve this you would need to reopen paperclip, which i would not recommend (because i believe the api is good the way it is).

The only way i can think of to solve this, is to add eliminate the file level too. Like so:

photo.width      --> photo.attachment.width
photo.file --> photo.attachment.file
photo.url --> photo.attachment.file.url

This you could then solve by using a delegate for each of the wanted methods.

So you write

class Photo
delegate :width, :height, :file, :to => :attachment
delegate :url, :to => :'attachment.file'
end

Hope this helps.

How to compare strings against command prompt input in Ruby

gets takes in the eol character as well, so use gets.chomp to only take in the actual string. The chomp method removes your carriage returns as well as your newlines.

As far as the string comparison goes, it's a little more ruby like to just compare whether or not your input exists in an array of predefined strings instead of chaining && and eql?, for example:

while not %w(up down close).include? action do

This is cleaner than the chaining, and makes it easier to modify too.

Is there a main method in Ruby like in C?

@Hauleth's answer is correct: there is no main method or structure in Ruby. I just want to provide a slightly different view here along with some explanation.

When you execute ruby somefile.rb, Ruby executes all of the code in somefile.rb. So if you have a very small project and want it to be self-contained in a single file, there's absolutely nothing wrong with doing something like this:

# somefile.rb

class MyClass
def say_hello
puts "Hello World"
end
end

def another_hello
puts "Hello World (from a method)"
end

c = MyClass.new
c.say_hello
another_hello

It's not that the first two blocks aren't executed, it's just that you don't see the effects until you actually use the corresponding class/method.

The if __FILE__ == $0 bit is just a way to block off code that you only want to run if this file is being run directly from the command line. __FILE__
is the name of the current file, $0 is the command that was executed by the shell (though it's smart enough to drop the ruby), so comparing the two tells you precisely that: is this the file that was executed from the command line? This is sometimes done by coders who want to define a class/module in a file and also provide a command-line utility that uses it. IMHO that's not very good project structure, but just like anything there are use cases where doing it makes perfect sense.

If you want to be able to execute your code directly, you can add a shebang line

#!/usr/bin/env ruby

# rest of somefile.rb

and make it executable with chmod +x somefile.rb (optionally rename it without the .rb extension). This doesn't really change your situation. The if __FILE__ == $0 still works and still probably isn't necessary.

Edit

As @steenslag correctly points out, the top-level scope in Ruby is an Object called main. It has slightly funky behavior, though:

irb
>> self
=> main
>> self.class
=> Object
>> main
NameError: undefined local variable or method `main' for main:Object
from (irb):8

Don't worry about this until you start to dig much deeper into the language. If you do want to learn lots more about this kind of stuff, Metaprogramming Ruby is a great read :)

Show every line of output of an external command in real time

Use IO.popen or Open3.

IO.popen("echo 1; sleep 1; echo 2; sleep 1; echo 3") do |io|
io.each_line do |line|
puts line
end
end


Related Topics



Leave a reply



Submit