I have a few lines of code that I would rather call as a function that paste in every time I need to call it. I know how to do this in C++ but not sure if it works the same in Ruby or how it works.
if op2_health < 0
op2_health = 0
#result = op1_name + ' Wins!'
elsif op1_health < 0
op1_health = 0
#result = op2_name + ' Wins'
end
That is the code I want to use as a function but I don't know the function syntax in Ruby. Thanks!
Define the function with def:
def my_function
if #op2_health < 0
#op2_health = 0
#op1_name + ' Wins!'
elsif #op1_health < 0
#op1_health = 0
#op2_name + ' Wins'
end
end
Then call it like this:
#result = my_function
I don't know your business rules, but are you sure, for example, that those conditions are mutually exclusive? Regardless, this should be the way to express your code as a reusable function--perhaps with some minor tweaks though for your situation.
I have identified the problem: Elsif isn't a word.
Related
I am trying to make Order number incremental in Spree 3.1.
I got only this:
Spree::Order.class_eval do
before_validation(on: :create) do
self.number = Spree::Core::NumberGenerator.new(prefix: 'S').send(:generate_permalink, Spree::Order)
end
end
but it's only change prefix.
How should I rewrite new_candidate to get right result?
#lib/spree/core/number_generator.rb
def new_candidate(length)
#prefix + length.times.map { #candidates.sample(random: #random) }.join
end
You can try this:
def new_candidate(host)
max_number = host.maximum(:number) || STARTING_NUMBER
#prefix + (max_number.gsub(#prefix, '').to_i + 1).to_s
end
def generate_permalink(host)
new_candidate(host)
end
You will need to define STARTING_NUMBER constant in the generator class. Also, you will not need the #length instance variable anymore.
I recently worked on a similar task to have an order number that contains the date of the order + a randomly generated number (for uniqueness).
To achieve this I add an order_decorator.rb into models/spree and I override the generate_number method:
// First i redefine the length for my random number
NUMBER_LENGTH = 5
def generate_number(options = {})
options[:length] ||= NUMBER_LENGTH
date = Date.today.strftime('%d-%m-%Y')
possible = (0..9).to_a
random = "-#{(0...options[:length]).map { possible.shuffle.first }.join}"
self.number ||= date + random
end
I don't like the generation of the random number (I would use `SecureRandom for it) but i left it initially was in Spree because for this it will do fine for my needs.
In your case you can add inside the method the code you need to make your number incremental.
I hope this helps!
Cheers
I get a task to make this code slower. I can change just inside the method. The reason, why I do this is to try ruby profiling. How or where can I can change a code to make it slower?
class FibonacciSequence
def next_fib
#index += 1
if #seq[#index].nil?
f = #seq[#index - 1] + #seq[#index - 2]
#seq[#index] = f
return f
else
return #seq[#index]
end
end
def current_fib
return #index >= 0 ? #seq[#index] : nil
end
def current_index
return #index >= 0 ? #index : nil
end
def [](n)
return nil if n < 0
return #seq[n] if n <= #index
while #index < n
self.next_fib
end
return self.current_fib
end
end
sleep(num_secs) is best way.
Other than this is calling function multiple times, itterate through loops, make array/hash say 1000 elements in it and apply methods like sort, map, on it,
reading remote file, reading huge data and process it (get 1000 users name and convert them all to uppercase. here you can read row in db and update some data clone it and save it back also help, if your db is remote this will give you more lag :)
But sleep is best way as you can comment just 1 line and this code will be optimum or you can change time parameter as you need.
i dont understand how to use this method from pcap_simple(https://github.com/ryanbreed/pcap_simple/blob/master/lib/pcap_simple.rb) gem, what is &block?
def each(&block)
file.seek(PCAP_HEADER_LEN)
loop do
header_data=file.read(PACKET_HEADER_LEN)
break if (header_data.nil? || header_data.length < PACKET_HEADER_LEN)
header=PcapRecord.new(header_data)
raw=file.read(header.incl_len)
break if (raw.nil? || raw.length < header.incl_len)
packet=Packet.new(:raw_data=>raw,:header=>header)
yield packet unless packet.datagram.nil?
end
end
and "yield packet", i know packet is a class but how it work with yield??
I tried something like this but nothing, the fist line work I could open the file.
#archivo = PcapSimple::PcapFile.new("file_name","/home/deniel/Sites Ruby on Rails/h2/out.pcap")
#archivo.each() do
logger.info "HELLLLLLLLLLLLLLLLLLLLLLLLLLO!"
end
Sorry and Thanks! im new in ruby.
I made it work copy-paste the gem method directly on my class like this way.
#file=File.open("/home/deniel/Sites Ruby on Rails/h2/out2.pcap","r")
#header=PcapHeader.new(#file.read((5*32 + 2*16)/8))
#file.seek((5*32 + 2*16)/8)
loop do
header_data = #file.read((5*32 + 2*16)/8)
break if (header_data.nil? || header_data.length < ((4*32)/8) )
header=PcapRecord.new(header_data)
raw=#file.read(header.incl_len)
break if (raw.nil? || raw.length < header.incl_len)
packet=Packet.new(:raw_data=>raw,:header=>header)
logger.info packet.src
end
So... I still dont know what is the
yield packet unless packet.datagram.nil?
and if i leave that line, appears this error:
LocalJumpError in WelcomeController#index
no block given
I am fairly new to Ruby and I am building a program that basically works as an interactive orchard, where the user will input what type of tree they want to grow and then give commands to water, prune, pick and harvest the tree.
The problem I am having is when I try to have the program ask for commands until the tree dies which occurs at a certain height. The height is defined in an instance variable inside a class, and I can't seem to figure out how to have the program track that variable outside of the class, so that it keeps prompting for a command until a certain value is achieved.
The below code is the start and end of the code, but not the middle parts which seem to be working fine. Each of the commands at the bottom work once, but then the program ends.
Any help would be appreciated.
class Orangetree
def initialize name
#name = name
#height = 0
#branches = 0
#winter = false
#orangesontree = 0
#orangesinbasket = 0
#timeOfyear = 0
puts #name + 'Just Sprouted! What would you like to do with him?'
end
puts 'Welcome to the Orchard! What would you like to grow today?'
reply = gets.chomp
while reply != 'oranges'
puts 'I am sorry, we do not have that kind of tree, try again'
gets.chomp
end
oranges = Orangetree.new 'Woody '
while Orangetree |#height| <= 61
command = gets.chomp
if command == 'water'
puts oranges.rain
end
if command == 'pick'
puts oranges.pick
end
if command == 'prune'
puts oranges.prune
end
if command == 'harvest'
puts oranges.harvest
end
end
You cannot access an object's instance field outside of its class directly. Use a getter method.
Adding attr_writer :height to your class will give this to you.
Then you can reference the height outside the class with
while oranges.height <= 61
I'm writing a function that reads in an answer key, creates a question, and then associates the right answer with that questions. Here's my function:
def self.save_images_in_dir(dir)
answer_key_file = Dir.glob(dir+"/*.{rtf,txt}").first
answer_key = Array.new
if answer_key_file
puts "found key"
File.open(answer_key_file, "r") do |infile|
while (line = infile.gets)
if line.match(/^\d+[.]\s+/)
num = line.match(/\d+/)
answer = line.gsub(/\d+[.]\s+/,"") # Take out the 1.
answer.chomp!
answer_key.push(answer.to_s)#answer_key[num.to_s]=answer.to_s
puts "number #{num} is #{answer.to_s}"
end
end
end
end
images = Dir.glob("#{dir}*.{png,jpeg,jpg,gif}").sort_by {|file| File.ctime(file) }
counter = 0
answer_key.each do |q|
puts "before entering: #{q}"
end
images.each do |img|
q = self.new
q.tags = get_tags(img)
q.correct_answer = answer_key[counter]
puts "---------Answer is:#{answer_key[counter]}--------\n"
q.photo = File.open(img)
if q.correct_answer.nil?
puts "answer is nil"
end
counter = counter + 1
end
end
and here's a snippet of the output right before it enters the images.each block.
before entering: D
before entering: A
before entering: A
before entering: C
before entering: A
found key
---------Answer is:--------
answer is nil
Does anyone know why answer_key would "reset", and, furthermore, why answer_key.count would return 0 when evaluated within the images block? I understand that blocks should inherit the local scope from where they are called...any reason why answer_key would not be passed?
The mistake must be somewhere else, this code should work.
Write a few unit tests and refactor this method, it's trying to do too many things.
Also, when you loop over the images, you can get rid of counter and use each_with_index instead.