我几乎一直在使用Java,因为它刚出现,但在过去的五年中,它已经被烧毁了,即使是最简单的事情也变得多么复杂。我开始在我的精神科医生的推荐下学习Ruby,呃,我的意思是我的同事(年轻,冷静的同事 - 他们使用Macs!)。无论如何,他们不断重复的一件事是,Ruby是一种“灵活”的语言,而不是像Java那样的老式,更加拙劣的语言,但我真的不知道这意味着什么。有人能解释是什么让一种语言比另一种语言“更灵活”?请。我对动态类型有所了解,可以看出这对简洁有什么好处。 Ruby语法很漂亮。还有什么?动态打字是主要原因吗?
答案 0 :(得分:6)
这也是因为它是无类别的(在Java意义上)但完全面向对象(属性模式)所以你可以调用任何方法,即使没有定义,你仍然有机会动态响应调用,示例创建必要的方法。 Ruby也不需要编译,因此您可以根据需要轻松更新正在运行的应用程序。此外,对象可以在其生命周期中通过mixin突然从其他类/对象继承,因此它是另一个灵活点。无论如何我同意孩子们这种语言称为Ruby,它实际上和Java一样长,在许多方面都非常灵活和优秀,但我仍然无法同意它的美丽(语法方面),C是更美丽的恕我直言(我是支架的傻瓜),但美是主观的,红宝石的其他品质是客观的
答案 1 :(得分:6)
动态类型并未接近覆盖它。举一个很好的例子,Ruby在许多情况下使元编程变得容易。在Java中,元编程要么是痛苦的要么是不可能的。
例如,采用Ruby通常的方式声明属性:
class SoftDrink
attr_accessor :name, :sugar_content
end
# Now we can do...
can = SoftDrink.new
can.name = 'Coke' # Not a direct ivar access — calls can.name=('Coke')
can.sugar_content = 9001 # Ditto
这不是一些特殊的语言语法 - 它是Module类的一个方法,而且很容易实现。以下是attr_accessor
的示例实现:
class Module
def attr_accessor(*symbols)
symbols.each do |symbol|
define_method(symbol) {instance_variable_get "@#{symbol}"}
define_method("#{symbol}=") {|val| instance_varible_set("@#{symbol}", val)}
end
end
end
这种功能可以让您在表达程序时获得很多灵活性。
许多看起来像语言功能(以及大多数语言中的语言功能)都只是Ruby中的常用方法。再举一个例子,这里我们动态加载其名称存储在数组中的依赖项:
dependencies = %w(yaml haml hpricot sinatra couchfoo)
block_list %w(couchfoo) # Wait, we don't really want CouchDB!
dependencies.each {|mod| require mod unless block_list.include? mod}
答案 2 :(得分:5)
块,闭包,很多东西。我肯定会在早上出现一些更好的答案,但是举一个例子,这是我十分钟前写的一些代码 - 我有一系列的scheduled_collections,其中一些已经发生,其他已经废弃,取消等等我想返回一个只有待处理数组的数组。我不确定等效的Java是什么,但我想这不是这种单行方法:
def get_all_pending
scheduled_collections.select{ |sc| sc.is_pending? }
end
同样事情的一个更简单的例子是:
[0,1,2,3].select{|x| x > 1}
哪个会产生[2,3]
答案 3 :(得分:4)
我喜欢的东西
[1, 2, 3].each{|x| puts "Next element #{x}"}
答案 4 :(得分:2)
混入。改变Ruby类以添加新功能非常简单。
答案 5 :(得分:2)
Duck typing 指的是当类型被它们实现的方法视为等效时,而不是基于它们声明的类型。举一个具体的例子,Ruby中的许多方法都采用类似IO的对象来操作流。这意味着对象必须实现足够的功能才能作为IO类型对象传递(它必须听起来像鸭子一样)。
最后,这意味着您必须编写比Java更少的代码来执行相同的操作。但是,关于动态语言的一切都不是很好。您或多或少会放弃Java(以及其他强/静态类型语言)为您提供的所有编译时类型检查。 Ruby根本不知道你是否要将错误的对象传递给方法;这会给你一个运行时错误。此外,在实际调用代码之前,它不会给您一个运行时错误。
答案 6 :(得分:2)
只是为了笑,这是语言灵活性的一个相当令人讨厌的例子:
class Fixnum
def +(other)
self - other
end
end
puts 5 + 3
# => 2