Ruby Freeze Method
def track_for stat
      # This is a hash with 2 elements of proc
      {
        symbol: -> { send(stat) },
        array:  -> { send(stat[0], stat[1]) }
      }.freeze[stat.class.name.underscore.to_sym].call
end

freeze[stat.class.name.underscore.to_sym].call , I have no idea about this code. What is the function of the code inside [], and why use call method? Anyone who can help me? Much appreciate it.

3 Answers

Ruby Freeze method done following things on different objects, basically it's make object constant or immutable in ruby.

  1. String
str = "this is string"
str.freeze

str.replace("this is new string") #=> FrozenError (can't modify frozen String)
or
str[0] #=> 't'
str[0] = 'X' #=> FrozenError (can't modify frozen String)

But you can assign new string or change its reference. Once the reference change then it is not freeze (or constant) object.

str = "this is string"
str.freeze
str.frozen? #=> true
str = "this is new string"
str.frozen? #=> false

  1. Array :-
arr = ['a', 'b', 'c']
arr.freeze

arr << 'd' #=> FrozenError (can't modify frozen Array)
arr[0] = 'd' #=> FrozenError (can't modify frozen Array)
arr[1].replace('e') #=> ["a", "e", "c"]
arr.frozen? #=> true

arr array is frozen means you can’t change the array. But the strings inside the array aren’t frozen. If you do a replace operation on the string “one”, mischievously turning it into “e”, the new contents of the string are revealed when you reexamine the (still frozen!) array.

  1. Hash
hash = {a: '1', b: '2'}
hash.freeze

hash[:c] = '3' #=> FrozenError (can't modify frozen Hash)
hash.replace({c: '3'}) #=> FrozenError (can't modify frozen Hash)
hash.merge({c: '3'}) #=> return new hash {:a=>"1", :b=>"2", :c=>"3"}
hash.merge!({c: '4'}) #=> FrozenError (can't modify frozen Hash)
hash.frozen? #=> true

hash = {:a=>"1", :b=>"2", :c=>"3"}
hash.frozen? #=> false

So we can't modify the hash content but we can refer it to new hash (just like array)

  • freeze - prevents modification to the Hash (returns the frozen object)
  • [] - accesses a value from the hash
  • stat.class.name.underscore.to_sym - I assume this returns a lowercase, snake case version of the given object's class name (underscore is not in the standard library, so I'm not completely sure)
  • call invokes the lambda associated with stat.class.name.underscore.to_sym key.

For instance, passing ['foo', 'bar'] as the argument to track_for would invoke the send(stat[0], stat[1]) lambda.

1

If we untangle the code it could be translated to:

def track_for stat
  case stat
    when Symbol
      send(stat)
    when Array
      send(stat[0], stat[1]) 
  end
end

The hash in the code is used to choose the correct behavior according to the variable stat's class.

Actually, I don't see any virtue in the OP code above over the translated code - it is less readable and has no runtime benefits (as far as I can see)...

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Sophia Al-Mansoor

Sophia Al-Mansoor

Global Business & E-Commerce Reporter

Sophia analyzes international trade, startup ecosystems, retail transformation, and supply chain logistics for modern digital publications.

Share this article
Twitter Facebook Pinterest