memo | Dmytro Shteflyuk's Home https://kpumuk.info In my blog I'll try to describe about interesting technologies, my discovery in IT and some useful things about programming. Mon, 07 Sep 2015 23:45:46 +0000 en-US hourly 1 https://wordpress.org/?v=6.7.1 Memo #6: Using named routes and url_for outside the controller in Ruby on Rails https://kpumuk.info/ruby-on-rails/memo-6-using-named-routes-and-url_for-outside-the-controller-in-ruby-on-rails/ Thu, 16 Jul 2009 12:11:50 +0000 http://kpumuk.info/?p=498 Sometimes we need to write small console scripts which do some background processing on our models. In Scribd we are using Loops to run these tasks (check Alexey Kovyrin’s introduction post). One of our scripts supposed to generate some sort of html reports, and we need to generate links to our site there. In Ruby […]

The post Memo #6: Using named routes and url_for outside the controller in Ruby on Rails first appeared on Dmytro Shteflyuk's Home.]]>
Sometimes we need to write small console scripts which do some background processing on our models. In Scribd we are using Loops to run these tasks (check Alexey Kovyrin’s introduction post). One of our scripts supposed to generate some sort of html reports, and we need to generate links to our site there.

In Ruby on Rails we are using routes to generate any sort of links. So let’s include routing mechanism into our own script or class.

First, you need to ensure that Rails core is loaded (if you haven’t done this earlier; for example, in script/console you should not do this). I’m assuming you’re creating a script under /script folder:

1
2
3
ENV['RAILS_ENV'] ||= 'production'
require File.dirname(__FILE__) + '/../config/boot'
require RAILS_ROOT + '/config/environment'

Now you need to include ActionController::UrlWriter module, which allows to write URLs from arbitrary places in your codebase, and configure default_url_options[:host]:

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# this is slow because all routes and resources being calculated now
include ActionController::UrlWriter
default_url_options[:host] = 'www.example.com'

# map.connect ':controller/:action/:id'
url_for(:controller => 'folders', :action => 'show', :id => Folder.first)
# => "http://www.example.com/folders/2"

# map.resources :folders
folders_url
# => "http://www.example.com/folders"
folder_url(Folder.first)
# => "http://www.example.com/folders/2"
edit_folder_url(Folder.first)
# => "http://www.example.com/folders/2/edit"

# you can use relative paths too
folders_path
# => "/folders"

Easy and helpful technique. Enjoy!

The post Memo #6: Using named routes and url_for outside the controller in Ruby on Rails first appeared on Dmytro Shteflyuk's Home.]]>
Memo #5: Use ary.uniq method carefully in Ruby https://kpumuk.info/ruby-on-rails/memo-5-use-ary-uniq-method-carefully-in-ruby/ https://kpumuk.info/ruby-on-rails/memo-5-use-ary-uniq-method-carefully-in-ruby/#comments Wed, 15 Jul 2009 10:55:17 +0000 http://kpumuk.info/?p=721 Today my friend asked me to help him with an unexpected behavior of Ruby’s Hash.uniq method. Here is an example: 123456[{"id"=>667824693}, {"id"=>667824693}].uniq # => [{"id"=>667824693}, {"id"=>667824693}] [{"id"=>66782469}, {"id"=>66782469}].uniq # => [{"id"=>66782469}] [{"id"=>6678246931}, {"id"=>6678246931}].uniq # => [{"id"=>6678246931}] Check the first command result. Very disappointing, right? So what happen? Quick looking through the Ruby code completely explained […]

The post Memo #5: Use ary.uniq method carefully in Ruby first appeared on Dmytro Shteflyuk's Home.]]>
Today my friend asked me to help him with an unexpected behavior of Ruby’s Hash.uniq method. Here is an example:

1
2
3
4
5
6
[{"id"=>667824693}, {"id"=>667824693}].uniq
# => [{"id"=>667824693}, {"id"=>667824693}]
[{"id"=>66782469}, {"id"=>66782469}].uniq
# => [{"id"=>66782469}]
[{"id"=>6678246931}, {"id"=>6678246931}].uniq
# => [{"id"=>6678246931}]

Check the first command result. Very disappointing, right? So what happen? Quick looking through the Ruby code completely explained it. Here is how this method works internally (this is just prototype in Ruby, original code is in C, but works in the same way):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def ary_make_hash(ary, val)
  ary.inject({}) do |hash, el|
    hash[el] = val
    hash
  end
end

def uniq(ary)
  ary = ary.dup
  ary.uniq!
  ary
end

def uniq!(ary)
  hash = ary_make_hash(ary, 0)
  return nil if ary.length == hash.length

  j = 0
  (0...ary.length).each do |idx|
    if hash.delete(ary[idx])
      ary[j] = ary[idx]
      j += 1
    end
  end
  ary.slice!(0, j)
  ary
end

Let’s test it:

1
2
3
4
5
6
uniq([{"id"=>667824693}, {"id"=>667824693}])
# => [{"id"=>667824693}, {"id"=>667824693}]
uniq([{"id"=>66782469}, {"id"=>66782469}])
# => [{"id"=>66782469}]
uniq([{"id"=>6678246931}, {"id"=>6678246931}])
# => [{"id"=>6678246931}]

And just to make sure our conclusions are correct:

1
2
3
4
5
6
[{"id"=>667824693}, {"id"=>667824693}].map { |el| el.hash }
# => [29793216, 29793156]
[{"id"=>66782469}, {"id"=>66782469}].map { |el| el.hash }
# => [255119887, 255119887]
[{"id"=>6678246931}, {"id"=>6678246931}].map { |el| el.hash }
# => [482552381, 482552381]

So the idea behind the Hash.uniq method is the method Hash.hash, which produces different results for hashes in the first example. Be careful when doing obj.uniq on complex objects.

Update: There is a good research on Hash.hash method here.

The post Memo #5: Use ary.uniq method carefully in Ruby first appeared on Dmytro Shteflyuk's Home.]]>
https://kpumuk.info/ruby-on-rails/memo-5-use-ary-uniq-method-carefully-in-ruby/feed/ 4
Memo #4: Managing Ruby Gems https://kpumuk.info/ruby-on-rails/memo-4-managing-ruby-gems/ https://kpumuk.info/ruby-on-rails/memo-4-managing-ruby-gems/#comments Mon, 13 Apr 2009 10:07:43 +0000 http://kpumuk.info/?p=422 The power of Ruby is not only in its flexibility. It allows to create easy to maintain reusable parts of software, and also provides a way to redistribute them and integrate with your applications — RubyGems system. The only thing that could hurt developer’s brain is managing installed gems. When you are updating already installed […]

The post Memo #4: Managing Ruby Gems first appeared on Dmytro Shteflyuk's Home.]]>
RubyGems The power of Ruby is not only in its flexibility. It allows to create easy to maintain reusable parts of software, and also provides a way to redistribute them and integrate with your applications — RubyGems system. The only thing that could hurt developer’s brain is managing installed gems. When you are updating already installed gem, previous version will stay in gems folder and will be available to use. But why do you need all these obsolete libraries? There is a command to cleanup stale libraries in RubyGems — gem cleanup.

First thing I want to mention is gems documentation. Every gem in system has powerful documentation based on rdoc, built during an installation procedure. The easiest way to view these docs is to run gem server and open http://localhost:8808/ in browser:

1
gem server

You will be able to review which gems has been installed, and check their documentation.

I’m pretty sure you have lots of gems with the same name, but different versions. You could use the following command to remove all gem versions except the latest one:

1
gem cleanup

That’s all. You have only latest gems installed. But wait, what about Max OS X users, who have pre-installed Ruby? They (actually we) are in trouble, because…

Fixing problem with gem cleanup on Mac OS X 10.5.x (Leopard)

On Mac OS X when you will try to use this command, you will hit following error:

1
2
Attempting to uninstall sqlite3-ruby-1.2.1
ERROR:  While executing gem ... (Gem::InstallError)

That’s common problem and I will show how to fix it. First, run following command:

1
2
3
4
5
6
7
8
9
10
11
12
kpumuk@kpumuk-mbp~: gem list -d sqlite3

*** LOCAL GEMS ***

sqlite3-ruby (1.2.4, 1.2.1)
    Author: Jamis Buck
    Homepage: http://sqlite-ruby.rubyforge.org/sqlite3
    Installed at (1.2.4): /Library/Ruby/Gems/1.8
                 (1.2.1): /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8

    SQLite3/Ruby is a module to allow Ruby scripts to interface with a
    SQLite3 database.

You may now uninstall the offending gem with:

1
gem uninstall --install-dir  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8 sqlite3-ruby

So, in general

1
gem list -d <gem-name>

will get you the location of the gem, and

1
gem uninstall --install-dir </install/directory> <gem-name>

will uninstall the gem (found here.)

The post Memo #4: Managing Ruby Gems first appeared on Dmytro Shteflyuk's Home.]]>
https://kpumuk.info/ruby-on-rails/memo-4-managing-ruby-gems/feed/ 3
Memo #3: Advanced usage of Ruby hashes and arrays https://kpumuk.info/ruby-on-rails/memo-3-advanced-usage-of-ruby-hashes-and-arrays/ https://kpumuk.info/ruby-on-rails/memo-3-advanced-usage-of-ruby-hashes-and-arrays/#comments Fri, 23 Jan 2009 00:59:58 +0000 http://kpumuk.info/?p=254 One of the most used features in any programming language is a Hash. Today we are going to talk about some of the Ruby’s Hash features, which are well documented, but rarely used — parameters of the Hash constructor. In the second part of this article we will take a look at the arguments of […]

The post Memo #3: Advanced usage of Ruby hashes and arrays first appeared on Dmytro Shteflyuk's Home.]]>
Ruby One of the most used features in any programming language is a Hash. Today we are going to talk about some of the Ruby’s Hash features, which are well documented, but rarely used — parameters of the Hash constructor. In the second part of this article we will take a look at the arguments of the Array class’ constructor.

Take a look at the following example.

1
2
3
4
5
6
a = %w(apple banana apple)
h = a.inject({}) do |h, fruit|
  h[fruit] ||= 0
  h[fruit] += 1
  h
end

Here we have an array of fruits and we need to calculate a frequency of each fruit. As you can see, in the line 3 we are initializing frequency value to 0 if there are was no fruit with this name before. We can simplify this code:

1
2
3
4
5
a = %w(apple banana apple)
h = a.inject(Hash.new(0)) do |h, fruit|
  h[fruit] += 1
  h
end

In line 2 we are creating a new hash, which default value is 0. This means that if we would try to retrieve value for a non-existing key, 0 would be returned.

Let’s check another example:

1
2
3
4
5
6
a = %w(apple banana apple)
h = {}
a.each_with_index do |fruit, i|
  h[fruit] ||= []
  h[fruit] << i
end

Here we are collecting indexes of each fruit in the source array. But now we can’t just create a new hash and pass [] as the default value, because all keys in this hash will refer to the same array, so in result we will get an array [1, 2, 3] for each fruit. So let’s try the following:

1
2
3
4
5
a = %w(apple banana apple)
h = Hash.new { |h, key| h[key] = [] }
a.each_with_index do |fruit, i|
  h[fruit] << i
end

In this case we are creating a new array object for any non-existing key, that was accessed. So

1
  h['some non-existing key']

will return [] and save it in the hash. When you will hit this key next time, previously created array will be returned.

You can pass a block to Array constructor too. For example, you need an array with 10 random numbers:

1
2
a = []
10.times { a << rand(100) }

You can simplify it using map method:

1
a = (1..10).map { rand(100) }

But you can do it even easier:

1
a = Array.new(10) { rand(100) }

Next Memo will cover managing Ruby Gems, so stay tuned.

The post Memo #3: Advanced usage of Ruby hashes and arrays first appeared on Dmytro Shteflyuk's Home.]]>
https://kpumuk.info/ruby-on-rails/memo-3-advanced-usage-of-ruby-hashes-and-arrays/feed/ 6
Memo #2: Useful Git tricks with remote branches https://kpumuk.info/development/memo-2-useful-git-tricks-with-remote-branches/ https://kpumuk.info/development/memo-2-useful-git-tricks-with-remote-branches/#comments Mon, 22 Dec 2008 22:59:15 +0000 http://kpumuk.info/?p=245 Here in Scribd we are using Git as primary version control system. We have tons of branches created, merged and destroyed every day. Someday I hope to describe our workflow with Git, but today I want to write about some useful techniques of working with this incredible tool. It’s implied that you know what is […]

The post Memo #2: Useful Git tricks with remote branches first appeared on Dmytro Shteflyuk's Home.]]>
Git Here in Scribd we are using Git as primary version control system. We have tons of branches created, merged and destroyed every day. Someday I hope to describe our workflow with Git, but today I want to write about some useful techniques of working with this incredible tool.

It’s implied that you know what is Git itself and how to work with it. Below you can find some advanced tricks, that should be helpful for you (at least they were helpful for me).

As you may know, to remove local branch git branch -d branch_name command is used. But if this branch was pushed to the origin repo, it will never be deleted there. To remove a remote branch use the following command:

1
git push origin :branch_name

where branch_name — the name of your branch.

When you are working in a team, everybody can create and push their own branches, which will be retrieved from the Git server during git pull or git fetch. If a branch being removed from the server, it will remain in your local repo forever. To clean these stale branches up, use this:

1
git remote prune origin

Also don’t forget to take a look at the git_remote_branch command-line tool, which makes work with remote branches as easy as it is possible.

Have any questions? Ask me and I will answer you in following Memo– posts.

The post Memo #2: Useful Git tricks with remote branches first appeared on Dmytro Shteflyuk's Home.]]>
https://kpumuk.info/development/memo-2-useful-git-tricks-with-remote-branches/feed/ 3
Memo #1: Installing mysql and memcached gems on Mac OS X with MacPorts https://kpumuk.info/ruby-on-rails/memo-1-installing-mysql-and-memcached-gems-on-mac-os-x-with-macports/ https://kpumuk.info/ruby-on-rails/memo-1-installing-mysql-and-memcached-gems-on-mac-os-x-with-macports/#comments Mon, 22 Dec 2008 19:20:39 +0000 http://kpumuk.info/?p=215 I have not posted anything here for a long time. It’s hard to start blogging again, so I will write a short tips and tricks series called “Memo“. Today I’m going to talk about two Ruby gems I’m using in all my Ruby on Rails project: mysql and memcached. Every time I try to install […]

The post Memo #1: Installing mysql and memcached gems on Mac OS X with MacPorts first appeared on Dmytro Shteflyuk's Home.]]>
I have not posted anything here for a long time. It’s hard to start blogging again, so I will write a short tips and tricks series called “Memo“. Today I’m going to talk about two Ruby gems I’m using in all my Ruby on Rails project: mysql and memcached. Every time I try to install or update those gems on Mac OS X following error occurs:

1
2
3
Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
    ERROR: Failed to build gem native extension.

And then I’m googling on how to install these gems. It’s time simplify my life and post commands here.

Installing the ruby mysql gem on Mac OS X and MacPorts

Installing mysql5 from MacPorts:

1
sudo port install mysql5

Now we can install mysql gem:

1
2
3
4
kpumuk@kpumuk-mbp~: sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5
Building native extensions.  This could take a while...
Successfully installed mysql-2.7
1 gem installed

Installing the ruby memcached gem on Mac OS X and MacPorts

First you need to install memcached and libmemcached:

1
sudo port install memcached libmemcached

And then memcached gem:

1
2
3
4
kpumuk@kpumuk-mbp~: sudo env ARCHFLAGS="-arch i386" gem install memcached --no-ri --no-rdoc -- --with-libmemcached-dir=/opt/local
Building native extensions.  This could take a while...
Successfully installed memcached-0.12
1 gem installed

If you have any questions that could be covered in this series — ask me in comments.

The post Memo #1: Installing mysql and memcached gems on Mac OS X with MacPorts first appeared on Dmytro Shteflyuk's Home.]]>
https://kpumuk.info/ruby-on-rails/memo-1-installing-mysql-and-memcached-gems-on-mac-os-x-with-macports/feed/ 1