相关疑难解决方法(0)

Ruby - 参考引用或值?

我不明白为什么他们 Ruby按值传递所有参数,同时下面的代码证明了相反的情况:

class MyClass1
  @var1 = 123

  def get1
    @var1
  end

  def set1=value
    @var1 = value
  end
end

c1 = MyClass1.new
c1.set1 = 444
p c1.get1 # 444

def test1 mc
  mc.set1 = 999
end

test1 c1
p c1.get1 # 999
Run Code Online (Sandbox Code Playgroud)

如果按价值计算,它会打印出来444,而不是999.

ruby

16
推荐指数
1
解决办法
1万
查看次数

如果在Ruby中一切都是对象,为什么这不起作用?

考虑到在Ruby编程语言中,一切都被称为对象,我安全地假设将参数传递给方法是通过引用完成.然而,下面这个小例子让我困惑:

$string = "String"

def changer(s)
  s = 1
end

changer($string)

puts $string.class
String
 => nil
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,原始对象未被修改,我希望知道为什么,以及如何实现所需的行为,即.获取方法实际更改其参数引用的对象.

ruby parameter-passing pass-by-reference

12
推荐指数
2
解决办法
1万
查看次数

不带参数调用超级

根据模块和类文档,调用super(不带参数或括号)使用相同的参数调用父方法:

在没有任何参数的情况下super使用时,使用给予子类方法的参数.

为"参数变量"分配新值似乎改变了这种行为:

class MyClass
  def foo(arg)
    puts "MyClass#foo(#{arg.inspect})"
  end
end

class MySubclass < MyClass
  def foo(arg)
    puts "MySubclass#foo(#{arg.inspect})"
    super
    arg = 'new value'
    super
  end
end

MySubclass.new.foo('inital value')
Run Code Online (Sandbox Code Playgroud)

输出:

MySubclass#foo("inital value")
MyClass#foo("inital value")
MyClass#foo("new value")       # <- not the argument given to MySubclass#foo
Run Code Online (Sandbox Code Playgroud)

这是预期的吗?

更新

似乎是位置和关键字参数的预期行为,但它不适用于块参数:

class MyClass
  def foo(&block)
    puts "MyClass#foo { #{block.call.inspect} }"
  end
end

class MySubclass < MyClass
  def foo(&block)
    puts "MySubclass#foo { #{block.call.inspect} }"
    super …
Run Code Online (Sandbox Code Playgroud)

ruby

11
推荐指数
1
解决办法
3992
查看次数

如何在哈希的开头添加键/值对?

我的代码是:

hash = { two: 2, three: 3 }

def hash_add(hash, new_key, new_value)
  temp_hash = {}

  temp_hash[new_key.to_sym] = new_value
  temp_hash.merge!(hash)
  hash = temp_hash
  puts hash

end

hash_add(hash, 'one', 1)
Run Code Online (Sandbox Code Playgroud)

在方法中,puts hash返回{ :one => 1, :two => 2, :three => 3 },但是当hash1放入方法时,它在之后保持不变.这就像赋值不在函数之外.

我想我可以返回更新的哈希并在方法之外设置我想要更改的哈希:

hash = hash_add(hash, 'one', 1)
Run Code Online (Sandbox Code Playgroud)

但我只是不明白为什么我给哈希的赋值不会超出方法.

我有这个,有效:

def hash_add(hash, new_key, new_value)
  temp_hash = {}

  temp_hash[new_key.to_sym] = new_value
  temp_hash.merge!(hash)
  hash.clear

  temp_hash.each do |key, value|
    hash[key] = value
  end
end
Run Code Online (Sandbox Code Playgroud)

这给了我调用这个方法时我想要的东西,但是像这样重建哈希似乎有点过分了.

ruby hash

10
推荐指数
2
解决办法
7659
查看次数

Rails 4.1和4.2之间ActiveRecord Setter的区别?

我们将我们的应用程序从Rails 4.1.14升级到4.2.5.1,并遇到以下问题:

string = "SomeString"
ar_model = SomeArModel.new
ar_model.some_attribute = string

# next line is true for 4.1, but fails for 4.2
ar_model.some_attribute.object_id == string.object_id
Run Code Online (Sandbox Code Playgroud)

显然,对象设置器复制每个对象(如果我有一个数组,内部的每个对象也将被欺骗),我想知道,如果这是有意的并且是一些新的安全功能的一部分?

更新

我使用ruby-2.2.2p95作为两个rails版本.作为参考,我做了一个小项目:

rails new testproject
rails g model Building name:string
rails db:migrate
rails c
  >> b = Building.new
  >> name = "Testname"
  >> b.name = name
  >> name.object_id # => 70199493308960
  >> b.name.object_id # => 70199493278780
Run Code Online (Sandbox Code Playgroud)

之后,我只在Gemfile中将Rails版本更改为4.1.14,并再次尝试=>两个object_ids都是相同的.所以它不能依赖于Ruby版本......

UPDATE2

它也适用于ruby-2.2.3和JRuby 9.0.4.0 ... ar_model.attributes_before_type_cast['some_attribute']包含真实对象.

ruby activerecord ruby-on-rails

6
推荐指数
1
解决办法
245
查看次数

为什么在Ruby中有一个String#替换?

在浏览ruby文档时,我找到了替换方法,但我无法弄清楚这个方法的用例是什么.

我唯一能想到的就是内存管理(如果新字符串的长度小于或等于之前的长度,则不需要重新分配).

有任何想法吗 ?

ruby string replace

5
推荐指数
1
解决办法
342
查看次数

Ruby是按值传递还是按引用传递?

我基本上是一个java开发人员.我在红宝石工作了大约一年.与java不同,Ruby是一种纯粹的面向对象的编程语言.这是一个疑问.它是按值传递还是按引用传递?Java作为pass-by-value工作:"当传递基元时,我看到该值被复制并传递给方法.但是如果有对象,则引用被复制并传递给方法.引用包含对象的位置在堆中.在方法调用期间,只传递对象的位置.因此不会创建重复的对象.同样的对象被修改."

但是当我尝试下面的ruby代码片段时,我得到了与Java相同的结果:"在方法调用期间,数字就像一个原语(比如在java中),而数组就像java中一样完美引用".现在,我很困惑.如果ruby中的所有内容都是对象,那么在方法调用期间为什么数字对象会重复?

class A
  def meth1(a)
    a = a+5
    puts "a inside meth1---#{a}"
  end

  def meth2(array)
    array.pop
    puts "array inside meth2---#{array}"
  end
end


obj1 = A.new
aa=5
obj1.meth1(aa)
puts "aa-----#{aa}"

arr = [3,4,5]
obj1.meth2(arr)
puts "arr---#{arr}"
Run Code Online (Sandbox Code Playgroud)

结果:

一个内部meth1 --- 10

AA ----- 5

数组里面的meth2 --- 34

ARR --- 34

ruby java oop pass-by-reference pass-by-value

4
推荐指数
3
解决办法
5170
查看次数

在 Ruby 中递归展平数组

我很难理解为什么这段代码有效:

def flatten(array, result = [])
  array.each do |element|
    if element.is_a? Array
      flatten(element, result)
    else
      result << element
    end
  end
  result
end
Run Code Online (Sandbox Code Playgroud)

特别是,为什么它可以在不必将 flatten 方法调用的结果分配给结果数组的情况下工作,如下所示:

def flatten1(array, result = [])
  array.each do |element|
    if element.is_a? Array
      result = flatten(element, result)
    else
      result << element
    end
  end
  result
end
Run Code Online (Sandbox Code Playgroud)

两者都产生相同的输出:

p flatten [1,2,[3,4,[5,[6]]]]  # [1, 2, 3, 4, 5, 6]
p flatten1 [1,2,[3,4,[5,[6]]]] # [1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

ruby recursion

4
推荐指数
1
解决办法
1697
查看次数

Ruby'通过价值'澄清

好的,所以Ruby是'按值传递'.但是,如何在Ruby中精确定义"按引用传递"和"按值传递"?我用过这个答案传递参考值和传递值之间有什么区别?根据它,Ruby似乎是一个混合......

从技术上讲,Ruby似乎是"按值传递",区别在于当您将值传递给方法时该值不会获得COPIED.如果我们定义"value"=对象,并且"reference"=指向该对象的引用变量,那么"通过引用传递"是否有意义,如果它等同于"传递指向特定对象的引用变量"?然后,一旦传递了"引用",该方法就不会对对象进行COPY,而实际上具有可以直接操作的ORIGINAL对象本身(由变量引用).如我错了请纠正我.

编辑:我知道这个问题Ruby是通过引用还是通过值传递?但不同的人似乎对那里的参考/价值有不同的定义.

ruby

3
推荐指数
1
解决办法
202
查看次数

如何让我的数组只在Ruby中本地操作(在函数内)?

当我运行下面的ruby代码时,为什么我的数组被全局操作?我怎样才能在函数范围内操作数组?

a = [[1,0],[1,1]]

def hasRowsWithOnlyOnes(array)
  array.map { |row|
    return true if row.keep_if{|i| i != 1 } == []
  }
  false;
end

puts a.to_s
puts hasRowsWithOnlyOnes(a)
puts a.to_s
Run Code Online (Sandbox Code Playgroud)

$ ruby test.rb 输出:

[[1, 0], [1, 1]]
true
[[0], []]
Run Code Online (Sandbox Code Playgroud)

我无法让它发挥作用.我甚至试过.select{true}把它分配给一个新名字.范围如何在Ruby for Arrays中运行?仅供参考$ ruby -v:

ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]
Run Code Online (Sandbox Code Playgroud)

ruby arrays scope

3
推荐指数
1
解决办法
84
查看次数