Ukesh’s Weblog

Ruby 1.8.x to 1.9.x

Posted in ruby on rails by ukesh on August 23, 2013

Ruby 1.8.x to 1.9.x

The major features and some of the most important improvements in ruby 1.9 are

  1.  Much better performance
  2.  Threads and Fibers(ie., Fibers are light-weight threads with manual, cooperative scheduling)
  3.  Added a brand new encoding engine and also supports Unicode
  4.  Rubygems is built-in now

Below are the changes made in Ruby 1.9.x from 1.8.x :
Single character strings.

Ruby 1.9 :
“cat”[1] => “a”
Ruby 1.8 :
“cat”[1] => 97

String index.

Ruby 1.9 :
“cat”[1] => “a”
Ruby 1.8 :
“cat”[1] => 97

{“a”,”b”} no longer supported.

Ruby 1.9 :
{1,2} => SyntaxError: (irb):2: syntax error, unexpected ‘,’, expecting tASSOC
Ruby 1.8 :
{1,2} => {1=>2}

Array.to_s now contains Punctuation.

Ruby 1.9 :
[1,2,3].to_s => “[1, 2, 3]”
Ruby 1.8 :
[1,2,3].to_s => “123”

Block variables now shadow local variables.

Ruby 1.9 :
i=0; [1,2,3].each {|i|}; i => 0
i=0; for i in [1,2,3]; end; i => 3
Ruby 1.8 :
i=0; [1,2,3].each {|i|}; i => 3

Inject methods.

Ruby 1.9 :
[1,2].inject(:+)
Ruby 1.8 :
[1,2].inject {|a,b| a+b}

Lambda shorthand syntax.

Ruby 1.9 :
p = -> a,b,c {a+b+c}
puts p.(1,2,3)
puts p[1,2,3]
Ruby 1.8 :
p = lambda {|a,b,c| a+b+c}
puts p.call(1,2,3)

In Hash classes some changes has be made

1. Hash finally preserves insertion order.

Ruby 1.9 :
hash = {:a=> ‘A’, :b=>’B’, :c=>’C’, :d=>’D’}
hash.keys ====>  [:a, :b, :c, :d]
hash.values ====> [“A”, “B”, “C”, “D”]
Ruby 1.8 :
hash = {:a=> ‘A’, :b=>’B’, :c=>’C’, :d=>’D’}
hash.keys ====>  [:b, :c, :d, :a]
hash.values ====> [“B”, “C”, “D”, “A”]

2. Hash#to_s behaves much nicer.

Ruby 1.9 :
hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
hash.to_s ====> “{:a=>1, :b=>2, :c=>3, :d=>4}”
Ruby 1.8 :
hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
hash.to_s ====> “b2c3d4a1″

3. Hash#select now returns a hash, not an array.

Ruby 1.9 :
hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
hash.select{|k,v| k == :c } ====> {:c=>3}
Ruby 1.8 :
hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
hash.select{|k,v| k == :c }  ====> [[:c, 3]]

Complex numbers.

Ruby 1.9 :
Complex(3,4) == 3 + 4.im

Decimal Is Still Not The Default.

Ruby 1.9 :
1.2-1.1 => 0.0999999999999999

Basic git commands

Posted in git by ukesh on November 26, 2010

Need to do an initial commit:
mkdir dir_name
cd dir_name
git init
git add .
git commit

Repository cloning:
git clone repository_url

Add a file:
git add file_path

What are the things you modified and added locally
git status

Commit the files:
git commit

git pull
git push origin master(after commit need to push the files)

Need to see the commits
git log

Delete a Remote Branch from GitHub
git push origin :branch_name

Browse Button with css style

Posted in Css by ukesh on October 12, 2010

Hi All,

Here i have create a simple HTML file with the browse button(added some css style).

<html>
<head>
<style>
#filefield {
position:relative;
}

#show_filefield {
position: absolute;
top: 0px;
left: 0px;
z-index: 1;
background:url(images.jpeg) 100% 0px no-repeat;
height:26px;
width:240px;
}

#upload_field {
width:155px;
height:26px;
margin-right:85px;
font-size:16px;
border:solid 1px #000;
}

#hide_filefield {
position:relative;
width:240px;
height:26px;
text-align: right;
-moz-opacity:0 ;
filter:alpha(opacity: 0);
opacity: 0;
z-index: 2;
}
</style>
</head>
<body>
<div id=”filefield”>
<input type=”file” size=”24″ id=”hide_filefield” onchange=”getElementById(‘upload_field’).value = getElementById(‘hide_filefield’).value;” />
<div id=”show_filefield”><input type=”text” id=”upload_field” /></div>
</div>
</body>
</html>

 

Thanks

Regular Expression

Posted in Regular expression by ukesh on September 16, 2010

Only String = /^[a-zA-Z]+$/
ex: “Therock”

Only Digits = /^\d+$/
ex: “3215”

Alphanumeric and underscore = /^\w+$/ or /^[a-zA-Z0-9\_]+$/
ex: address,address_1

Email = /^[\w\.]+@\w+\.[a-z]{1,3}$/
ex: rails@gmail.com, rails_get@gmail.com

Mobile Number(starts with ‘+’ and only 12 digits) = /^\+\s\d{12}$/
ex: +919999988888

Get left side value
ex: “ukesh kumar”.scan(/(.*)\s/).flatten.to_s

Get right side value
ex: “ukesh kumar”.scan(/\s(.*)/).flatten.to_s

Standard Username/login = /^\w[\w\.+\-_@ ]+$/
ex: ukesh86, uk.esh

Get left side value
ex: “ukesh kumar”.s

Get right side value
ex: “ukesh kumar”.s

Standard Username
ex: ukesh86, uk.esh

Using Regular Expression to get alpha-numeric values in an Array

Posted in Regular expression by ukesh on September 16, 2010

>> a = %w{a m 1 4 @ ) *}
=> [“a”, “m”, “1”, “4”, “@”, “)”, “*”]
>> a.select{|x| x =~ /\w/}
=> [“a”, “m”, “1”, “4”]

Components of a Time

Posted in ruby on rails by ukesh on May 25, 2010

require ‘rubygems’

time = Time.new

# Components of a Time
puts “Current Time : ” + time.inspect
puts time.year    # => Year of the date
puts time.month   # => Month of the date (1 to 12)
puts time.day     # => Day of the date (1 to 31 )
puts time.wday    # => 0: Day of week: 0 is Sunday
puts time.yday    # => 365: Day of year
puts time.hour    # => 23: 24-hour clock
puts time.min     # => 59
puts time.sec     # => 59
puts time.usec    # => 999999: microseconds
puts time.zone    # => “UTC”: timezone name

Tagged with: ,

acts_as_taggable

Posted in ruby on rails by ukesh on April 18, 2008

The acts_as_taggable(plugin), although built in to Rails, is basically deprecated. And the gem version is old and requires a separate join table for every taggable model, which is silly .

update

Please see the updated has_many_polymorphs documentation, which has instructions for using the new, built-in tagging generator.

install

Uninstall whatever acts_as_taggable version you have, to prevent fighting among the plugins. Then, install has_many_polymorphs:

script/plugin install -x svn://rubyforge.org/var/svn/fauna/has_many_polymorphs/trunk

models

We will assume you are using the default acts_as_taggable models. You should have a Tag model, with a name field, as well as a Taggings join model. However, these models are part of the acts_as_taggable plugin source, whereas their migrations have to be part of your app (which is confusing). Instead, with has_many_polymorphs, we have to make the models part of the app, too:

class Tag < ActiveRecord::Base
has_many_polymorphs :taggables,
:from => [:books, :magazines],
:through => :taggings,
:dependent => :destroy
end

class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :taggable, :polymorphic => true

def before_destroy
# disallow orphaned tags
tag.destroy_without_callbacks if tag.taggings.count < 2
end
end

See the line [:books, :magazines]? This line replaces all the acts_as_taggable macro calls strewn through your models. Simply list in the array the models that you want to be able to tag. (You can even tag Tags, see below.)

migrations

We need to make sure your existing tag schema fits this. It should be something like:

class AddTagSupport < ActiveRecord::Migration
def self.up
create_table :tags do |t|
t.column :name, :string, :null => false
end
add_index :tags, :name, :unique => true

create_table :taggings do |t|
t.column :tag_id, :integer, :null => false
t.column :taggable_id, :integer, :null => false
t.column :taggable_type, :string, :null => false
end
add_index :taggings, [:tag_id, :taggable_id, :taggable_type], :unique => true
end

def self.down
drop_table :tags
drop_table :taggings
end
end

If your schema isn’t like this already, you have two choices. You can add more options to the association macros in your models, to show them how to relate to your schema, or you can write a migration to convert your schema into canonical form. The first option is possibly quicker to implement, but the second one will be easier to maintain.

api

Hey, you’re done! Well, not really. The API is different, which is the biggest sticking point. We’ll write some convenience methods to mimic the old way. You should put the methods in RAILS_ROOT/lib/tag_extensions.rb or similar.

class ActiveRecord::Base
def tag_with tags
tags.split(" ").each do |tag|
Tag.find_or_create_by_name(tag).taggables << self
end
end

def tag_list
tags.map(&:name).join(' ')
end
end

Pretty straightforward, which makes it easy to modify. For example, to make creating a model from params more transparent, we could add:

alias :tags= :tag_with

Or to enforce lowercase tags, just do:

def tag_with tags
tags.downcase.split(" ").each do |tag|
Tag.find_or_create_by_name(tag).taggables << self
end
end

If you want to allow tags with spaces in them, we can accept an array instead of a string:

def tag_with *tags
tags.flatten.each do |tag|
Tag.find_or_create_by_name(tag).taggables << self
end
end

To delete tags (don’t forget to downcase the tag_string if you need to):

def tag_delete tag_string
split = tag_string.split(" ")
tags.delete tags.select{|t| split.include? t.name}
end

To get all models for a tag (and all in a single SQL query, thanks to the plugin):

Tag.find_by_name("artichoke").taggables

To get only a specific model for a tag:

Tag.find_by_name("artichoke").books

Easy and powerful. And if you need to find which tags are most popular, see here.

Make sure that you require the file containing your API methods in environment.rb, since Rails won’t load it automatically:

require 'tag_extensions'

performance note

It is more efficient if we add :skip_duplicates => false to the has_many_polymorphs :taggables call. Then the taggables for each Tag won’t get loaded at all during the <<, because there is no reason to check them.

If we do this, though, and use database constraints to enforce uniqueness, we need to manually rescue assignment errors in our tag_with method:

def tag_with tags
tags.split(" ").each do |tag|
begin
Tag.find_or_create_by_name(tag).taggables << self
rescue ActiveRecord::StatementInvalid => e
raise unless e.to_s[/Duplicate entry/]
end
end
end

self-referential tagging

What if you want to be able to tag tags? This is more useful than might first appear. It lets you create an ad-hoc non-exclusive hierarchy of categories without extra models. This is much more maintainable than one based on hard-coded models for each level. But you need some way to distinguish “the tags tagged by a tag” and “the tags a tag is tagged by”—a directed graph. So we will rename the parent relationship:

class Tag < ActiveRecord::Base
has_many_polymorphs :taggables,
:from => [:books, :magazines, :tags],
:through => :taggings,
:dependent => :destroy,
:as => :tagger
end

class Tagging < ActiveRecord::Base
belongs_to :tagger,
:class_name => "Tag",
:foreign_key => "tagger_id"
belongs_to :taggable,
:polymorphic => true
end

Modify the migration accordingly. Now, you can use some_tag.taggables to get the targets of some_tag, and some_tag.taggers to get the tags for which some_tag is itself a target.

Note that your tag_delete method might have to be more longwinded due to this long-outstanding Rails bug.

Index Merge Optimization

Posted in mysql by ukesh on April 11, 2008

The Index Merge method is used to retrieve rows with several range scans and to merge their results into one. The merge can produce unions, intersections, or unions-of-intersections of its underlying scans. This access method merges index scans from a single table; it does not merge scans across multiple tables.

Note

If you have upgraded from a previous version of MySQL, you should be aware that this type of join optimization is first introduced in MySQL 5.0, and represents a significant change in behavior with regard to indexes. (Formerly, MySQL was able to use at most only one index for each referenced table.)

In EXPLAIN output, the Index Merge method appears as index_merge in the type column. In this case, the key column contains a list of indexes used, and key_len contains a list of the longest key parts for those indexes.

Examples:

SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

SELECT * FROM tbl_name
WHERE (key1 = 10 OR key2 = 20) AND non_key=30;

SELECT * FROM t1, t2
WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')
AND t2.key1=t1.some_col;

SELECT * FROM t1, t2
WHERE t1.key1=1
AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);

The Index Merge method has several access algorithms (seen in the Extra field of EXPLAIN output):

  • Using intersect(...)
  • Using union(...)
  • Using sort_union(...)

The following sections describe these methods in greater detail.

Note

The Index Merge optimization algorithm has the following known deficiencies:

  • If a range scan is possible on some key, the optimizer will not consider using Index Merge Union or Index Merge Sort-Union algorithms. For example, consider this query:
    SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;

    For this query, two plans are possible:

    • An Index Merge scan using the (goodkey1 < 10 OR goodkey2 < 20) condition.
    • A range scan using the badkey < 30 condition.

    However, the optimizer considers only the second plan.

  • If your query has a complex WHERE clause with deep AND/OR nesting and MySQL doesn’t choose the optimal plan, try distributing terms using the following identity laws:
    (x AND y) OR z = (x OR z) AND (y OR z)
    (x OR y) AND z = (x AND z) OR (y AND z)
  • Index Merge is not applicable to fulltext indexes. We plan to extend it to cover these in a future MySQL release.

The choice between different possible variants of the Index Merge access method and other access methods is based on cost estimates of various available options.

How MySQL Uses Indexes

Posted in mysql by ukesh on April 11, 2008

Indexes are used to find rows with specific column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows. The larger the table, the more this costs. If the table has an index for the columns in question, MySQL can quickly determine the position to seek to in the middle of the data file without having to look at all the data. If a table has 1,000 rows, this is at least 100 times faster than reading sequentially. If you need to access most of the rows, it is faster to read sequentially, because this minimizes disk seeks.

Most MySQL indexes (PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT) are stored in B-trees. Exceptions are that indexes on spatial data types use R-trees, and that MEMORY tables also support hash indexes.

Strings are automatically prefix- and end-space compressed.

In general, indexes are used as described in the following discussion. Characteristics specific to hash indexes (as used in MEMORY tables) are described at the end of this section.

MySQL uses indexes for these operations:

  • To find the rows matching a WHERE clause quickly.
  • To eliminate rows from consideration. If there is a choice between multiple indexes, MySQL normally uses the index that finds the smallest number of rows.
  • To retrieve rows from other tables when performing joins. MySQL can use indexes on columns more efficiently if they are declared as the same type and size. In this context, VARCHAR and CHAR are considered the same if they are declared as the same size. For example, VARCHAR(10) and CHAR(10) are the same size, but VARCHAR(10) and CHAR(15) are not.

    Comparison of dissimilar columns may prevent use of indexes if values cannot be compared directly without conversion. Suppose that a numeric column is compared to a string column. For a given value such as 1 in the numeric column, it might compare equal to any number of values in the string column such as '1', ' 1', '00001', or '01.e1'. This rules out use of any indexes for the string column.

  • To find the MIN() or MAX() value for a specific indexed column key_col. This is optimized by a preprocessor that checks whether you are using WHERE key_part_N = constant on all key parts that occur before key_col in the index. In this case, MySQL does a single key lookup for each MIN() or MAX() expression and replaces it with a constant. If all expressions are replaced with constants, the query returns at once. For example:
    SELECT MIN(key_part2),MAX(key_part2)
    FROM tbl_name WHERE key_part1=10;
  • To sort or group a table if the sorting or grouping is done on a leftmost prefix of a usable key (for example, ORDER BY key_part1, key_part2). If all key parts are followed by DESC, the key is read in reverse order.
  • In some cases, a query can be optimized to retrieve values without consulting the data rows. If a query uses only columns from a table that are numeric and that form a leftmost prefix for some key, the selected values may be retrieved from the index tree for greater speed:
    SELECT key_part3 FROM tbl_name
    WHERE key_part1=1

Suppose that you issue the following SELECT statement:

mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

If a multiple-column index exists on col1 and col2, the appropriate rows can be fetched directly. If separate single-column indexes exist on col1 and col2, the optimizer will attempt to use the Index Merge optimization or attempt to find the most restrictive index by deciding which index finds fewer rows and using that index to fetch the rows.

If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to find rows. For example, if you have a three-column index on (col1, col2, col3), you have indexed search capabilities on (col1), (col1, col2), and (col1, col2, col3).

MySQL cannot use an index if the columns do not form a leftmost prefix of the index. Suppose that you have the SELECT statements shown here:

SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

If an index exists on (col1, col2, col3), only the first two queries use the index. The third and fourth queries do involve indexed columns, but (col2) and (col2, col3) are not leftmost prefixes of (col1, col2, col3).

A B-tree index can be used for column comparisons in expressions that use the =, >, >=, <, <=, or BETWEEN operators. The index also can be used for LIKE comparisons if the argument to LIKE is a constant string that does not start with a wildcard character. For example, the following SELECT statements use indexes:

SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';

In the first statement, only rows with 'Patrick' <= key_col < 'Patricl' are considered. In the second statement, only rows with 'Pat' <= key_col < 'Pau' are considered.

The following SELECT statements do not use indexes:

SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;

In the first statement, the LIKE value begins with a wildcard character. In the second statement, the LIKE value is not a constant.

If you use ... LIKE '%string%' and string is longer than three characters, MySQL uses the Turbo Boyer-Moore algorithm to initialize the pattern for the string and then uses this pattern to perform the search more quickly.

A search using col_name IS NULL employs indexes if col_name is indexed.

Any index that does not span all AND levels in the WHERE clause is not used to optimize the query. In other words, to be able to use an index, a prefix of the index must be used in every AND group.

The following WHERE clauses use indexes:

... WHERE index_part1=1 AND index_part2=2 AND other_column=3
/* index = 1 OR index = 2 */
... WHERE index=1 OR A=10 AND index=2
/* optimized like "index_part1='hello'" */
... WHERE index_part1='hello' AND index_part3=5
/* Can use index on index1 but not on index2 or index3 */
... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;

These WHERE clauses do not use indexes:

    /* index_part1 is not used */
... WHERE index_part2=1 AND index_part3=2

/*  Index is not used in both parts of the WHERE clause  */
... WHERE index=1 OR A=10

/* No index spans all rows  */
... WHERE index_part1=1 OR index_part2=10

Sometimes MySQL does not use an index, even if one is available. One circumstance under which this occurs is when the optimizer estimates that using the index would require MySQL to access a very large percentage of the rows in the table. (In this case, a table scan is likely to be much faster because it requires fewer seeks.) However, if such a query uses LIMIT to retrieve only some of the rows, MySQL uses an index anyway, because it can much more quickly find the few rows to return in the result.

Hash indexes have somewhat different characteristics from those just discussed:

  • They are used only for equality comparisons that use the = or <=> operators (but are very fast). They are not used for comparison operators such as < that find a range of values.
  • The optimizer cannot use a hash index to speed up ORDER BY operations. (This type of index cannot be used to search for the next entry in order.)
  • MySQL cannot determine approximately how many rows there are between two values (this is used by the range optimizer to decide which index to use). This may affect some queries if you change a MyISAM table to a hash-indexed MEMORY table.
  • Only whole keys can be used to search for a row. (With a B-tree index, any leftmost prefix of the key can be used to find rows.)

Ruby – unpack & pack

Posted in ruby on rails by ukesh on March 4, 2008

Program:

hal = “My Name is BILLA”
ascii = hal.unpack(“C*”)
# We can’t use Array#each since we can’t mutate a Fixnum
ascii.collect! { |i|
i + 6                         # add one to each ASCII value
}
ibm = ascii.pack(“C*”)
puts ibm

order=ibm.unpack(“C*”)
order.collect! {|x| x-6 }
re=order.pack(“C*”)

puts re

Output:

Encrption method:   DUPLICATE –>  S&Tgsk&oy&HORRG
Decription method : ORIGINAL –> My Name is BILLA

Regadrs,

UKESH

Tagged with: , ,
Follow

Get every new post delivered to your Inbox.