你需要仔细再看看@mizuhashi举的例子,他的例子里 params[:id] 是 credit_card 的 id,不是 user 或 accout 的 id。他所说的情况是 user 没有跟内层资源直接关联,而是跟外层资源关联。
你直接将@c写在类里 (元类也是类),而不是写在方法里,这种变量是类实例变量(class instance variable)
,而不是实例变量。它跟实例变量的用法并不一样。所以这个问题并不是实例变量
的坑。
重写 csrf_meta_tags 方法可以改 csrf-param
def csrf_meta_tags
if protect_against_forgery?
[
tag("meta", name: "csrf-param", content: request_forgery_protection_token),
tag("meta", name: "csrf-token", content: form_authenticity_token)
].join("\n").html_safe
end
end
?.等价于'.',?\n等价于'\n'。说白了就是单个字符,不过项目中不建议使用
没有区别,别名关系
Enumerator.instance_method(:with_object) == Enumerator.instance_method(:each_with_object)
返回 true
额。你把多个不同意义的参数封在了一个数组里,这个例子才会这么麻烦。如果是foo(arr: nil, size: nil, default: nil)
就清晰多了,内部的判断也就变成了if arr
。如果内部逻辑麻烦的话,我一般会拆成几个方法,再由 foo 提供统一接口 (如果需要有统一接口的话)
搞不懂为什么这个例子要判断元素的类型,跟 Array 的 initialize 有什么关系?给个更有实际意义的例子吧。。。
就是普通的逻辑运算,常用于短路操作。几乎等价于&&,但优先级更低。
用Storage.singleton_class.class_eval
来定义类方法挺繁琐的,在项目中一般直接用Storage.instance_eval
或者在类中用class<<self
打开单例类
文件中,在顶级作用域中定义的方法会成为 Object 的 private 方法,所以你在文件中定义 meet,所有对象也会继承这个方法,只是它是 private 的,调用时要省略调用者,或者使用 send。而在 irb 的顶级作用域中定义的方法会成为 Object 的 public 方法,所以你可以直接显式调用。至于为什么会有这样的处理方式,我也木有看过比较权威的说法
楼主的例子说了这么多,我的理解就是数组去重。。。
没咋倒腾过算法,自己写怎么都要遍历一次吧 (O(n) 的时间复杂度),随手写大概是这样:a.each_with_object({}){|ar, hsh| hsh[ar] = true}.keys
,不知道能不能跑赢a.uniq!
。楼主把代码贴出来撒
ruby 项目里要是有人这么写会被群嘲的。楼主以前写过 ruby,看来之前学的 ruby 基础就不咋牢靠。。。
楼主描述问题的时候需要更准确一点,一是因为 ruby 里不把@nilv称为成员变量,而叫实例变量 (楼主是写 java 的吧?),二是因为 test 方法是不会报"error"的,只是 test 方法没有达到你期望的效果而已(看完这里,楼主是不是要机智的修改问题描述了)。
没达到效果的原因是 ruby 把get_nilv = 3
解释成了局部变量赋值,你在 test 中加上一行p get_nilv
就会发现输出了 3。如果你想让 ruby 把它解释成方法名而不是变量名,需要使用self.get_nilv=3
。当然,这时候才会真正的报 error,提示你没有get_nilv=
这个 setter 方法。这个带等号的标识符是方法名,而 3 是它的参数(如果楼主看到这里表示很惊讶的话,就需要反思自己的 ruby 学习历史是不是遗漏了很多东西)。你可以定义get_nilv=
这个方法来解决问题,不过你更需要了解attr_accessor
这个类方法,这时候你就会知道以上代码有多奇怪了。。。
以上知识点应该是任何一本 ruby 基础书籍前 4 章的内容,建议楼主还是先停下 leetcode,仔细的看看书吧。
原来如此。我就很奇怪为什么会有这么多人跑偏。也看不到问题编辑历史。。。
除了@jjym,楼上诸位的答案都跑偏了。
楼主说的应该是列表生成式,不过示例代码并不完整,推断代码应该是[x + 1 for x in [1,2,3]]
,其实就是把 for in 语句写在一行里,再省略了列表容器 (python 的列表相当于 ruby 中的数组)。这段 py 代码等价于 ruby 中的[1,2,3].map{|x| x+1}
。
更复杂的列表生成式[m + n for m in 'XY' for n in 'AB']
,实际上就是个嵌套的 for in 循环,结果是 ['XA', 'XB', 'YA', 'YB'],用 ruby 写出来是'XY'.chars.product('AB'.chars).map(&:join)
(可能有更优雅的写法)。
如同@jjym所说,ruby 中的枚举方法和 block 可以实现列表生成式的效果。个人认为这种语法在 ruby 中显得不那么面向对象,毕竟 ruby 一直倡导使用 each 等枚举方法来替代 for in 语句。相信有很多人都没有在 (或者极少在)ruby 中使用 for in。
楼上的方法可行,不过更直接的方式是
100.downto(0)
大兄弟,首先你的代码有问题,times 方法本身就能实现迭代了,为啥还要接个 each 方法?所以你这个问题表述也不对了,整个表达式的结果实际是 each 方法的返回值,而不是 times 的。
其次,api 文档里写的很清楚,无论 times 还是 each,在接了代码块的时候,返回的都是 self。多看 API 啊
values = [[1,2,3,4,5],[9,8,7,6,5]]
attributes = [:attr_1, :attr_2, :attr_3, :attr_4, :attr_5]
pairs = values.map { |v| attributes.zip(v).to_h }
tabel.where(:data_type => @type).each {|rcd| rcd.update_attributes(pairs.shift)}
没有测试过
在《重构--ruby 版》一书中,作者详细描述过临时变量是代码的 bad smell,具体原因我只记得一点了,就是临时变量不能在方法之间共用(也有可能我没记住关键的原因)。作者倡导定义查询方法替换临时变量。其实我觉得严格按照作者说的做有点矫枉过正,实际上在项目中,我也不会把木有复用需求的代码抽成方法。但是谁能保证以后一定没有复用需求呢?
赞。不过楼主应该把 ruby 的版本写出来。 在 ruby2.4.1 的版本中,class_variables 方法默认会把继承链上的类变量输出,例子中现在应该给 class_variables 加上 false 参数咯
先谢谢楼主的翻译,之前正在看英文版,结果一搜另一个问题就找到中文版 。 然后给楼主提个建议:“Enumerable 是急切的 (这里翻译的不好,想不出更好的词了)”。 建议楼主使用“贪婪”这个词,正则表达式中的“贪婪匹配”,rails 中的“贪婪加载”,对应的英文也是 eager