Notes posted to Ruby
RSS feedTotal Unique Elements: Set Union
For total unique elements, see set union: http://apidock.com/ruby/Array/|
Total Unique Elements from Two Arrays
Simple but thought it was worth mentioning:
( [ 1, 2, 3 ] + [ 3, 4, 5 ] ).uniq #=> [ 1, 2, 3, 4, 5 ]
See also: sample
sample randomly picks 1 or n elements from the array
Use kill 0 to find out if process is running
is_running.rb:
#!/usr/bin/env ruby pid = ARGV[0].to_i begin Process.kill(0, pid) puts "#{pid} is running" rescue Errno::EPERM # changed uid puts "No permission to query #{pid}!"; rescue Errno::ESRCH puts "#{pid} is NOT running."; # or zombied rescue puts "Unable to determine status for #{pid} : #{$!}" end
Thanks to http://stackoverflow.com/a/200568/51209
Not available
Actually, this method is not available now.(github.com/ruby/ruby/blob/trunk/rational.c#L2352)
Change in clone for ActiveRecord objects in ruby-1.9.3
I noticed that cloning an active record object in ruby-1.9.3 and then changing an attribute on the original object will actually change the cloned object as well. This was not the case in ruby-1.9.2.
Difference in the way returns are handled
Also, there is a difference in the way returns are handled from the Proc. A return from Proc.new returns from the enclosing method. Return in lambda-block acts like in regular method.
return example
def proc_return Proc.new { return "Proc.new"}.call return "proc_return method finished" end def lambda_return lambda { return "lambda" }.call return "lambda_return method finished" end puts proc_return puts lambda_return # => Proc.new # => lambda_return method finished
Unexpected rounding behavior
Both 2.5 and 1.5 are rounded to 2…
ree-1.8.7-2010.02 > sprintf("%.f", 0.5) => "0" ree-1.8.7-2010.02 > sprintf("%.f", 1.5) => "2" ree-1.8.7-2010.02 > sprintf("%.f", 2.5) => "2" ree-1.8.7-2010.02 > sprintf("%.f", 3.5) => "4" ree-1.8.7-2010.02 > sprintf("%.f", 4.5) => "4"
use round instead to get proper behavior
example will not work in 1.9+
Since 1.9 introduces native threads, we cannot assume the order of exectution and the example above is not thread safe and fails with a “deadlock detected (fatal)” error. Also Thread.pass is pointless in the context of native threads.
This will work as intended with native threads:
a = Thread.new { print "a"; Thread.stop; print "c" } sleep(0.1) until a.status == 'sleep' print "b" a.run a.join
Alternative way to show relative paths from absolute globbing
An alternative to show relative paths is using the well known String#sub! method
base_dir = File.expand_path("my_dir") << "/" # don't miss adding "/" files = Dir[File.join(base_dir, '**', '*.html.gz')] p files.map {|f| f.sub!(base_dir,"")}
now they are built-in
in ruby 1.9 and afterwards, the to_enum and enum_for(synonym for to_enum) methods are buil-in to the language. so there’s no need to require that any more.
Dup vs Clone difference
As for me main difference between .dup and .clone , that first one doesn’t not freeze result object if initial object was frozen.
Uses same arguments as Time#strftime
I believe this uses the same parsing format as strftime.
Loop through matches of your regular expression-based search
If you want to loop through the matches of a regular expression, String#scan is your friend. You can do something like this:
matches = '12345'.scan(/\d/) matches.each do |m| puts m end # => 1 # => 2 # => 3 # => 4 # => 5
Generalized Zip
My 5 cents.
I find trully useful this. Is a kind of generalized zip. You can combine 2 or more enumerables (arrays or others) of any size into a hash, array of arrays, .… The size of the result is the size of the bigest of the enumerables. For the shortests enumerables nil elements are used at the end.
# method compose def compose(*enumerables) res=[] enumerables.map(&:size).max.times do tupla=[] for enumerable in enumerables tupla << enumerable.shift end res << (block_given? ? yield(tupla) : tupla) end res end
some examples:
en1= [1, 2, 3, 4] en2= ['a', 'b', 'c', 'd', 'e'] en3= {:elem1 => "1", :elem2 => "2", :elem3 => "3"} p compose en1.dup, en2.dup, en3.dup p a1=compose(en2.dup, en1.dup) {|a,b| {a.to_sym => b}} p a1.inject({}) {|ac,item| ac.merge item} p a1.flatten p a2=compose(en2.dup, en1.dup).flatten p Hash[*a2] p a3=compose(en2.dup, en3.dup).flatten
Their outputs are:
#[[1, "a", [:elem1, "1"]], [2, "b", [:elem2, "2"]], [3, "c", [:elem3, "3"]], [4, "d", nil], [nil, "e", nil]] #[{:a=>1}, {:b=>2}, {:c=>3}, {:d=>4}, {:e=>nil}] #{:b=>2, :d=>4, :e=>nil, :c=>3, :a=>1} #[{:a=>1}, {:b=>2}, {:c=>3}, {:d=>4}, {:e=>nil}] #["a", 1, "b", 2, "c", 3, "d", 4, "e", nil] #{"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>nil} #["a", :elem1, "1", "b", :elem2, "2", "c", :elem3, "3", "d", nil, "e", nil]
Using New
-rails new ProjectName -switch directories -git repo “git init”, then commit -add gems, bundle install -rails g scaffold TableName attribute:type attribute:type….. -authentication -add attribute_accessible/relationships/validations -get rid of index.html in public, set root “table#index” -rails g nifty:layout -rake db:migrate -git repo -rails s, see if works -change id’s to names in show and indexes -images go to public/images -partials are rendered in application.html.erb
Backport from 1.9
Below is a backport of the Ruby 1.9 implementation (minus some encoding stuff). The main thing this provides you is the ability to say :foo => [‘bar’, ‘baz’] and have that turn into foo=bar&foo=baz (i.e. multiple values for the same key).
Just require into your project and use it like you are on 1.9.
module Net module HTTPHeader def set_form_data(params, sep = '&') query = URI.encode_www_form(params) query.gsub!(/&/, sep) if sep != '&' self.body = query self.content_type = 'application/x-www-form-urlencoded' end alias form_data= set_form_data end end module URI def self.encode_www_form(enum) enum.map do |k,v| if v.nil? k elsif v.respond_to?(:to_ary) v.to_ary.map do |w| str = k.dup unless w.nil? str << '=' str << w end end.join('&') else str = k.dup str << '=' str << v end end.join('&') end end
Remove non empty directories
To remove a non empty directory use FileUtils:
Dir.mkdir("test_dir") Dir.mkdir("test_dir/sub_dir") FileUtils.remove_dir("test_dir",true)
Working with match captures
Let’s say you wanted to filter out passwords from:
s = "password=bob&password=jim&password=jane"
You’d do this:
r = /password\=([^\&]+)/ s.gsub!(r) { |m| m.gsub!($1, "[FILTERED]") }
Which would return
password=[FILTERED]&password=[FILTERED]&password=[FILTERED]
Handling nested hashes and arrays
You can use this code to handle nested hashes and arrays. I’m not sure if it handles every case, and it could probably be refactored better, but it’s working quite well for us.
require 'active_support/core_ext/hash' def normalize_params(params, key=nil) params = params.flatten_keys if params.is_a?(Hash) result = {} params.each do |k,v| case v when Hash result[k.to_s] = normalize_params(v) when Array v.each_with_index do |val,i| result["#{k.to_s}[#{i}]"] = val.to_s end else result[k.to_s] = v.to_s end end result end # Adapted from http://snippets.dzone.com/posts/show/6776 class Hash def flatten_keys(newhash={}, keys=nil) self.each do |k, v| k = k.to_s keys2 = keys ? keys+"[#{k}]" : k if v.is_a?(Hash) v.flatten_keys(newhash, keys2) else newhash[keys2] = v end end newhash end end
String#crypt uses your platform's native implementation
Which cipher types (specified through the salt argument) are available will depend on what your platform natively supports. It should be noted that OSX up to at last 10.6 only provides the regular DES cipher. On most Linux platforms, however, you should have access to the following:
ID | Method --------------------------------------------------------- 1 | MD5 2a | Blowfish (not in mainline glibc; added in some | Linux distributions) 5 | SHA-256 (since glibc 2.7) 6 | SHA-512 (since glibc 2.7)
So on OSX, you might have:
ruby-1.9.2-p180 :001 > "password".crypt("$6$somesalt") => "$6FMi11BJFsAc"
But on Linux, you’ll get:
irb(main):001:0> "password".crypt("$6$somesalt") => "$6$somesalt$A7P/0Yfu8RprY88D5T1n.xKT749BOn/IXBvmR1gXZzU7imsoTfZhCQ1916CB7WNX9eOOeSmBmmMrl5fQn9LAP1"
For more information on what your platform supports, see `man crypt`
Agree with Oleg
Yes, the only way round this seems to be to code e.g:
postArgs = { ‘table[field]’ => value, ‘table[f2]’ => v2 }
after the fashion of the browsers form definition.
This lets you do nested attributes as well, e.g: postargs[‘table[children_attributes[0][field]’] = value
Perfectly applicable
@rkh You would be correct if this code had occurred in a subclass who’s parent method was being overridden.
However, defining the method in this manner is completely removing the old method - as if you had written code like this:
class MyClass def do_something puts "We're doing some stuff here" end def do_something puts "The old do_something method no longer exists!" end end MyClass.new.do_something # => "The old do_something method no longer exists!"
Of course this is non-sensical. But the idea is that you have either included a module, or monkey-patched an already existent class, and completely replaced the old method. super(*args) will not work
flags
from ‘man recvfrom’
The flags argument to a recv() function is formed by or'ing one or more of the values: MSG_OOB process out-of-band data MSG_PEEK peek at incoming message MSG_WAITALL wait for full request or error The MSG_OOB flag requests receipt of out-of-band data that would not be received in the normal data stream. Some protocols place expedited data at the head of the normal data queue, and thus this flag cannot be used with such protocols. The MSG_PEEK flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue. Thus, a subsequent receive call will return the same data. The MSG_WAITALL flag requests that the opera- tion block until the full request is satisfied. However, the call may still return less data than requested if a signal is caught, an error or disconnect occurs, or the next data to be received is of a different type than that returned.
counts the length of non-uncode characters.
jlength counts the non-unicode characters in a string to its actual length. Otherwise rails treat as 5 characters.