_reader和Rails属于,因为它们都是在程序启动时调用的,然后(希望)再也不会调用。在程序的执行过程中定义方法会让你的速度慢很多。我猜这里有一个ruby开发人员的小社区。你知道吗,一旦你调用外部方法,任何人都可以调用内部方法?正如最后提到的,这对于l
_reader和Rails属于,因为它们都是在程序启动时调用的,然后(希望)再也不会调用。在程序的执行过程中定义方法会让你的速度慢很多。我猜这里有一个ruby开发人员的小社区。你知道吗,一旦你调用外部方法,任何人都可以调用内部方法?正如最后提到的,这对于l,ruby,metaprogramming,Ruby,Metaprogramming,_reader和Rails属于,因为它们都是在程序启动时调用的,然后(希望)再也不会调用。在程序的执行过程中定义方法会让你的速度慢很多。我猜这里有一个ruby开发人员的小社区。你知道吗,一旦你调用外部方法,任何人都可以调用内部方法?正如最后提到的,这对于lambdas来说是一个很好的例子,而不是定义一个方法。为此在类上定义一个新方法是严重的过度使用。我可以问一下为什么它是“严重过度使用”吗?据我所知,这只是使方法成为一个变量的区别,对吗?这并不是矫枉过正,但似乎是错误的,这取决于用例。这不仅仅是
_reader和Rails属于,因为它们都是在程序启动时调用的,然后(希望)再也不会调用。在程序的执行过程中定义方法会让你的速度慢很多。我猜这里有一个ruby开发人员的小社区。你知道吗,一旦你调用
外部方法
,任何人都可以调用内部方法
?正如最后提到的,这对于lambdas来说是一个很好的例子,而不是定义一个方法。为此在类上定义一个新方法是严重的过度使用。我可以问一下为什么它是“严重过度使用”吗?据我所知,这只是使方法成为一个变量的区别,对吗?这并不是矫枉过正,但似乎是错误的,这取决于用例。这不仅仅是使方法成为变量的区别。使用“def”将该方法公开为当前方法范围之外的实例方法。如果确实要清除实例方法,请使用define_方法,因为它更清晰。如果要使用仅在本地作用域中可用的匿名,请使用lambda。@bobics是正确的。如前所述,这是一段糟糕的代码。每次调用不同的实例方法时,都要重新定义实例方法。这是不必要的,令人困惑,甚至可能非常慢,因为每次调用#process_filter
时,它都会使Ruby的方法缓存失效。不要这样做。永远不要这样做。好吧,问题是关于嵌套def的,所以我试着去做。正如我所说,我的真实版本使用了lambdas。(而且比它所取代的要快得多。)我喜欢同样的做法。在方法中定义方法以简化代码并使其清晰。当您的方法变得很复杂,并且您不想为一个调用定义外部方法时,这是非常有用的。这不是一个好主意。Ruby没有注意到#score
中的def
,只定义了一次方法,每次(并且仅当)#score
运行时才定义它。这意味着#get#u set_score
不存在,直到调用#score
并且每次调用#get#u set_score
时都重新定义它。不仅如此,它还使Ruby的全局方法缓存失效,这将大大降低您的程序速度。完全同意Peeja的观点,因此除非该语言支持真正的内部方法,否则使用它们可能是不明智的(如果Ruby检测到这种情况,可能会发出警告,甚至错误?),这些方法确实定义了其他方法,但它们的实现看起来不像问题中的示例。这些方法是使用define\u method
定义实例方法的类方法。如果他们使用def
,他们会定义更多的类方法,这是没有用的。他们也不能将新方法的名称作为参数,因为def
不是一个接受参数的方法,而是一个需要在源代码中使用文字名称的语法构造。(实际上,有一点需要更正:在某些情况下,像这样的宏不使用define_方法
,而是构造一个包含def
构造和class_eval
字符串的字符串。但这仍然不等同于在def
中嵌套def
)(我没有注意到,从技术上讲,问题不是关于def
s中的def
s,而是关于从其他方法定义方法。您所说的绝对正确,您只是不应该按照示例中所示的方式来做。)
def outer_method
def inner_method
# ...
end
# ...
end
def process_filter(working_set,filter_type,filter_value)
working_set.select do |item|
case filter_spec
when "substring"
item.include?(filter_value)
when "equals"
item == filter_value
when "<="
item <= filter_value
...
end
end
end
def process_filter(working_set,filter_type,filter_value)
case filter_spec
when "substring"
def do_filter(item,filter_value)
item.include?(filter_value)
end
when "equals"
def do_filter(item,filter_value)
item == filter_value
end
when "<="
def do_filter(item,filter_value)
item <= filter_value
end
...
end
working_set.select {|item| do_filter(item,filter_value)}
end
class Scoring
# other code
def score(dice)
same, rest = split_dice(dice)
set_score = if same.empty?
0
else
die = same.keys.first
case die
when 1
1000
else
100 * die
end
end
set_score + rest.map { |die, count| count * single_die_score(die) }.sum
end
# other code
end
class Scoring
# other methods...
def score(dice)
same, rest = split_dice(dice)
set_score = same.empty? ? 0 : get_set_score(same)
set_score + get_rest_score(rest)
end
def get_set_score(dice)
die = dice.keys.first
case die
when 1
1000
else
100 * die
end
end
def get_rest_score(dice)
dice.map { |die, count| count * single_die_score(die) }.sum
end
# other code...
end
class Scoring
# other code
def score(dice)
def get_set_score(dice)
die = dice.keys.first
case die
when 1
1000
else
100 * die
end
end
def get_rest_score(dice)
dice.map { |die, count| count * single_die_score(die) }.sum
end
same, rest = split_dice(dice)
set_score = same.empty? ? 0 : get_set_score(same)
set_score + get_rest_score(rest)
end
# other code
end
get_rest_score = -> (dice) do
dice.map { |die, count| count * single_die_score(die) }.sum
end
...
set_score + get_rest_score.call(rest)
class Module
def attr_reader(name)
define_method(name) do
instance_variable_get("@#{name}")
end
end
end
class Module
def attr_reader(name)
def name
instance_variable_get("@#{name}")
end
end
end