Ruby - Prevent auto escape characters - ruby

I have e.g. r = "\t" and a = "thisisabigbad\wolf"
How can I prevent ruby from auto escaping my string and also count the \ at the same time?
a.count r #=> this should return 2 instead of 0
I wish to do a.count and receive 2

You can use single quotes:
[17] pry(main)> r = '\t'
=> "\\t"
[18] pry(main)> r.size
=> 2
[20] pry(main)> a = 'thisisabigbad\wolf'
=> "thisisabigbad\\wolf"
[21] pry(main)> a.size
=> 18

Related

My jsonpath expression returns two results when I expect just one

This piece of ruby code returns [1,1] but I expect to get just [1]. If I put the same text and jsonpath expression through http://jsonpath.com then I get [1]. Is this a bug in the 'jsonpath' gem?
require 'jsonpath'
string = <<-HERE_DOC
[
{"processId":1,"process":"XX"},
{"processId":2,"process":"YY"}
]
HERE_DOC
jsonpath = "$..[?(#.process=='XX')].processId"
path = JsonPath.new(jsonpath)
result = path.on(string)
puts "result: #{result}"
It seems that the problem is the extra point, in your jsonpath expression without this works similar in the two behaviours, you only need to go down one step:
[1] pry(main)> require 'jsonpath'
=> true
[2] pry(main)> jsonpath = "$.[?(#.process=='XX')].processId"
=> "$.[?(#.process=='XX')].processId"
[3] pry(main)> path = JsonPath.new(jsonpath)
=> #<JsonPath:0x00007f8c5bf42f10
#opts={},
#path=["$", "[?(#.process=='XX')]", "['processId']"]>
[4] pry(main)> string = <<-HERE_DOC
[4] pry(main)* [
[4] pry(main)* {"processId":1,"process":"XX"},
[4] pry(main)* {"processId":2,"process":"YY"}
[4] pry(main)* ]
[4] pry(main)* HERE_DOC
=> "[\n {\"processId\":1,\"process\":\"XX\"},\n {\"processId\":2,\"process\":\"YY\"}\n]\n"
[5] pry(main)> result = path.on(string)
=> [1]

Why is ruby acting like passing by reference when using gsub function in Ruby? [duplicate]

This question already has answers here:
Ruby 'pass by value' clarification [duplicate]
(3 answers)
Closed 4 years ago.
Given the following two methods:
[53] pry(main)> def my_method
[53] pry(main)* leti = 'leti'
[53] pry(main)* edit(leti)
[53] pry(main)* leti
[53] pry(main)* end
=> :my_method
[54] pry(main)> def edit(a_leti)
[54] pry(main)* a_leti.gsub!('e', '3')
[54] pry(main)* a_leti
[54] pry(main)* end
=> :edit
[55] pry(main)> my_method
=> "l3ti"
Can someone explain why I am getting the value edited inside the edit method and not the original value ('leti'). I though Ruby was passed by value. In fact, if instead of using the function gsub I use a simple assignment, I get the original value. Does the gsub! make it by reference?
Thank you!
In Ruby: Objects like strings are passed by reference. Variables with objects like strings are in fact references to those strings. Parameters are passed by value. However, for strings, these are references to those strings.
So here is the classic example:
irb(main):004:0* a = "abcd"
=> "abcd"
irb(main):005:0> b = a
=> "abcd"
irb(main):006:0> b << "def"
=> "abcddef"
irb(main):007:0> a
=> "abcddef"
irb(main):008:0> b
=> "abcddef"
If you do not wish to modify the original string, you need to make a copy of it:
Three ways (of many) to do this are:
b = a.dup
b = a.clone
b = String.new a
Using dup
irb(main):009:0> a = "abcd"
=> "abcd"
irb(main):010:0> b = a.dup
=> "abcd"
irb(main):011:0> b << "def"
=> "abcddef"
irb(main):012:0> a
=> "abcd"
irb(main):013:0> b
=> "abcddef"
BTW: For myself, this effect is the number one cause of defects in my own code.

Stack overflow while serializing user-defined Ruby objects to Riak

While working through http://docs.basho.com/riak/latest/dev/taste-of-riak/querying-ruby
I noticed what I can't store Time object in riak for some reason.
[3] pry(main)> client = Riak::Client.new(:protocol => "pbc", :pb_port => 8087, :host => "192.168.145.34")
=> #<Riak::Client [#<Node 192.168.145.34:8098:8087>]>
[4] pry(main)>
[5] pry(main)>
[6] pry(main)> tt = client.bucket('test')
=> #<Riak::Bucket {test}>
[7] pry(main)> v = tt.new("ttt")
=> #<Riak::RObject {test,ttt} [#<Riak::RContent [application/json]:nil>]>
[8] pry(main)> v.data = 1
=> 1
[9] pry(main)> v.store
=> #<Riak::RObject {test,ttt} [#<Riak::RContent [application/json]:1>]>
[10] pry(main)> v.data = Time.now
=> 2014-06-22 11:34:01 +0400
[11] pry(main)> v.store
SystemStackError: stack level too deep
from /home/maus/.gem/ruby/1.9.1/gems/pry-0.10.0/lib/pry/pry_instance.rb:353
After that I discovered what it's the case for user defined classes too:
[16] pry(main)> class Tst
[16] pry(main)* def initialize(x)
[16] pry(main)* #x = x
[16] pry(main)* end
[16] pry(main)* end
=> nil
[17] pry(main)> t111 = Tst.new(111)
=> #<Tst:0x9b13f4c #x=111>
[18] pry(main)> v.data = t111
=> #<Tst:0x9b13f4c #x=111>
[19] pry(main)> v.store
SystemStackError: stack level too deep
from /home/maus/.gem/ruby/1.9.1/gems/pry-0.10.0/lib/pry/pry_instance.rb:353
[20] pry(main)>
[21] pry(main)> v.data = [1,2,3]
=> [1, 2, 3]
[22] pry(main)> v.store
=> #<Riak::RObject {test,test_key} [#<Riak::RContent [application/json]:[1, 2, 3]>]>
Looks like something is terribly wrong with my install. But how to investigate it? I'm using riak-1.3.2 and ruby 1.9.3p194 with the following versions of gems:
i18n-0.6.9
builder-3.2.2
beefcake-0.3.7
multi_json-1.10.1
innertube-1.0.2
riak-client-1.4.4.1
The only place in the store method code path were I see the value being use is in BeefcakeProtobuffsBackend.ObjectMethods::dump_object which instantiates an RpbContent with :value => maybe_encode(robject.raw_data), so this would appear to be an issue with serializing the custom data.
RContent.raw_data calls Serializers::serialize
def serialize(content_type, content)
serializer_for(content_type).dump(content)
end
Serialize only understands a very few content types:
Serializers['text/plain'] = TextPlain
Serializers['application/json'] = ApplicationJSON
Serializers['application/x-ruby-marshal'] = ::Marshal
The default for content_type is application/json, whose dump method is:
def dump(object)
object.to_json(Riak.json_options)
end
Check that v.raw_data returns the value you expect, and if not, try setting v.content_type='text/plain'
For your custom class, make sure it has a to_json or to_s method that returns a string, and select the appropriate content_type.

Does pry or irb allow you to work interactively from inside a block?

I know that pry allows you to "cd" into other scopes.
pry(main)> cd Object
pry(Object)> ls
constants:
ARGF Encoding GC NIL
ArgumentError EncodingError Gem NilClass
ARGV Enumerable Hash Noexec
Array Enumerator IndexError NoMemoryError
...
But is there any way to move the interactive session into a block thats passed to a method?
pry(main)> cd some_instance.some_method do |some_argument|
pry(block)> ls
some_argument some_other_vars_available_within_block
pry(block)> end
result_of_block
pry(main)>
If possible, this would be exceedingly helpful. I've tried getting binding.pry to work myself in this fashion, without some luck, but I wanted to make sure I'm going down the right path before I continue.
Not sure i understand you fully, but you can try this, for example:
(master ✘)✹✭ ᐅ pry
[1] pry(main)> def hello(&block)
| Object.new.instance_exec(&block)
| end
=> nil
[2] pry(main)> block_binding = nil
=> nil
[3] pry(main)> hello { |some_argument = "testing"| u = 20; block_binding = binding }
=> #<Binding:0x007fdd33b1f680>
[4] pry(main)> cd block_binding
[5] pry(#<Object>):1> ls
locals: _ __ _dir_ _ex_ _file_ _in_ _out_ _pry_ _super block_binding some_argument u
[6] pry(#<Object>):1> some_argument
=> "testing"
[7] pry(#<Object>):1> u
=> 20
[8] pry(#<Object>):1> self
=> #<Object:0x007fdd33b1f888>
[9] pry(#<Object>):1>
Actually it turns out that nesting pry works beautifully. Kudos to the pry team.
Once I got my little binding.pry issue out of the way (my fault entirely).
Nesting pry: (note the 2 exit statements needed)
Hershwild:~ jstillwell$ pry
[1] pry(main)> binding.pry
[1] pry(main)> exit
=> nil
[2] pry(main)> exit
Hershwild:~ jstillwell$
Bringing forth pry from within a block:
Hershwild:~ jstillwell$ pry
[1] pry(main)> def test
[1] pry(main)* yield true
[1] pry(main)* end
=> nil
[2] pry(main)> test do |inside|
[2] pry(main)* binding.pry
[2] pry(main)* end
# after that end statement, pry resumes inside the block
[1] pry(main)> inside
=> true
[2] pry(main)> exit
=> nil
[3] pry(main)> exit
Hershwild:~ jstillwell$

In ruby, why does array append fail on a hash with a default value of empty array? [duplicate]

This question already has answers here:
Strange, unexpected behavior (disappearing/changing values) when using Hash default value, e.g. Hash.new([])
(4 answers)
Closed 7 years ago.
Code example below. Calling append on a hash value returns correctly but the hash itself doesn't behave as I would expect.
ruby-1.9.2-p290 :037 > r = {}
=> {}
ruby-1.9.2-p290 :038 > r.default = []
=> []
ruby-1.9.2-p290 :039 > r["c"] << 1
=> [1]
ruby-1.9.2-p290 :040 > r["c"]
=> [1]
ruby-1.9.2-p290 :041 > r
=> {}
ruby-1.9.2-p290 :042 > r.empty?
=> true
from the doc on default=:
Sets the default value, the value returned for a key that does not
exist in the hash. It is not possible to set the default to a Proc
that will be executed on each key lookup.
So you can use this:
irb(main):037:0> h = Hash.new { |hash, key| hash[key] = [] }
=> {}
irb(main):038:0> h[1] << "2"
=> ["2"]
irb(main):039:0> h
=> {1=>["2"]}
also you can use default_proc:
irb(main):047:0> h = {}
irb(main):047:0> h.default_proc = proc {|hash, key| hash[key] = []}
=> #<Proc:0x23939a0#(irb):47>
irb(main):049:0> h[1] << 3
=> [3]
irb(main):050:0> h
=> {1=>[3]}
It seems ruby hash uses r.default as default value for any r[<unassigned-key>]. So a single value is changed even if you specify different un-assigned keys. Please see below:
irb(main):001:0> r = {}
=> {}
irb(main):002:0> r.default = []
=> []
irb(main):003:0> r["c"] << 1
=> [1]
irb(main):004:0> r["c"]
=> [1]
irb(main):005:0> r["b"] << 2
=> [1, 2]
irb(main):006:0> r["b"]
=> [1, 2]
irb(main):007:0> r["c"]
=> [1, 2]
irb(main):010:0> r.default
=> [1, 2]
irb(main):008:0> r
=> {}
irb(main):009:0> r.empty?
=> true

Resources